We can get file extension on the server and set unique file name and extension by Multer.
Version
Node 16.16.0
Express 4.17.1
Alpine 3.10.3
Alpine
Upload single file by Alpine and Express.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script src="https://unpkg.com/alpinejs" defer></script>
<title>Upload</title>
</head>
<body x-data="fileUpload">
<input x-ref="upload" type="file" />
<button @click="onClick">Upload</button>
<div x-text="resMsg"></div>
</body>
<script>
let fileUpload = {
resMsg: '',
async onClick() {
let formData = new FormData()
formData.append('file', this.$refs.upload.files[0])
try {
let res = await fetch(`http://localhost:8080/upload`, {
method: 'POST',
body: formData,
})
let data = await res.json()
this.resMsg = data.message
} catch (e) {
console.error(e)
}
},
}
</script>
</html>
Line 8
<body x-data="fileUpload">
<input x-ref="upload" type="file" />
<button @click="onClick">Upload</button>
<div x-text="resMsg"></div>
</body>
x-data
:withfileUpload
Object to control the componentx-ref
:to set the name for the DOM element@click
:upload the file to the serverx-text
:display the result message
Line 17
let formData = new FormData();
formData.append("file", this.$refs.upload.files[0]);
fetch()
acceptsFormData
as argument forbody
- Append
file
key for uploaded file
Line 20
try {
let res = await fetch(`http://localhost:8080/upload`, {
method: 'POST',
body: formData,
})
let data = await res.json()
this.resMsg = data.message
} catch (e) {
console.error(e)
}
- Use
fetch()
API with methodPOST
and bodyformData
response.json()
:fetch()
returns Promise with Response Object, usejson()
to convert Response Object to JSON Object
Express
import express, { json } from 'express'
import cors from 'cors'
import multer, { diskStorage } from 'multer'
let app = express()
app.use(cors())
app.use(json())
let storage = diskStorage({
destination(req, file, cb) {
cb(null, 'uploads')
},
filename(req, file, cb) {
let extension = file.originalname.split('.').pop()
let uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9)
let filename = `${file.originalname}-${uniqueSuffix}.${extension}`
cb(null, filename)
},
})
let opts = multer({ storage }).single('file')
app.post('/upload', opts, (req, res) => {
res.json({ message: 'Successfully uploaded files' })
})
app.listen(8080, () => {
console.log('Node listen on port: 8080')
})
Line 1
import express, { json } from 'express'
import cors from 'cors'
import multer, { diskStorage } from 'multer'
- Import
express
、cors
andmulter
Line 5
let app = express()
- Create
app
Object for Express
Line 6
app.use(cors())
- Create
cors
middleware bycors()
- Use
cors
middleware by Express
Line 7
app.use(json())
- Create
json
middleware byjson()
. This is a built-in middleware by Express - Use
json
middleware by Express
Line 9
let storage = diskStorage({
destination(req, file, cb) {
cb(null, 'uploads')
},
filename(req, file, cb) {
let extension = file.originalname.split('.').pop()
let uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9)
let filename = `${file.originalname}-${uniqueSuffix}.${extension}`
cb(null, filename)
},
})
- Use
diskStorage()
to createstorage
Object for Multer options destination
:determine within which folder the uploaded files should be storedfilename
:determine what the file should be named inside the folder, get extension fromfile.originalname
, and set new name bycb()
Line 22
let opts = multer({ storage }).single('file')
- Create
opts
Object for Multer dest
:set folder to place filessingle
:upload single file by Multer, the argument forsingle()
must depend on the name for the input specified informData
in Alpine
Line 24
app.post('/upload', opts, (req, res) => {
res.json({ message: 'Successfully uploaded files' })
})
- Create
/upload
POST with Multer options - Use Object Destructuring to destructure
req
Object to get other POST data - Return JSON Object with successful message
Line 28
app.listen(8080, () => {
console.log('Node listen on port: 8080')
})
- Express listens on port
8080
Conclusion
- We can get file extension on the server by
file.originalname.split('.').pop()