We can provide unique file name by Client and specify this name to 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 newFileName = Date.now() + '-' + Math.round(Math.random() * 1E9)
let formData = new FormData()
formData.append('newFileName', newFileName)
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 newFileName = Date.now() + '-' + Math.round(Math.random() * 1E9)
- Determine a random file name
Line 19
let formData = new FormData()
formData.append('newFileName', newFileName)
formData.append('file', this.$refs.upload.files[0])
fetch()
acceptsFormData
as argument forbody
- Append
newFileName
key for other POST data - Append
file
key for uploaded file
Line 23
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 { body: { newFileName }} = req
cb(null, newFileName)
},
})
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 { body: { newFileName }} = req
cb(null, newFileName)
},
})
- 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, getnewFileNmae
fromreq
andcb()
to set new file name
Line 19
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 21
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 25
app.listen(8080, () => {
console.log('Node listen on port: 8080')
})
- Express listens on port
8080
Conclusion
- We can get POST data in
filename()
ofstorage
Object to set unique file name specified by client