Multer default changes the file name of uploaded files. If we want to keep the original file name, we have to write some code.
Version
Node 16.16.0
Express 4.17.1
Alpine 3.10.3
Alpine
Upload a single file by Alpine and Express with the original file name.
<!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 an argument forbody
- Append the
file
key for the 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) {
cb(null, file.originalname)
},
})
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) {
cb(null, file.originalname)
},
})
- 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
Line 18
let opts = multer({ storage }).single('file')
- Create
opts
Object for Multer dest
:usestorage
as the key for optionssingle
:upload single file by Multer, the argument forsingle()
must depend on the name for the input specified informData
in Alpine
Line 20
app.post('/upload', opts, (req, res) => {
res.json({ message: 'Successfully uploaded files' })
})
- Create
/upload
POST with Multer options - Return JSON Object with successful message
Line 24
app.listen(8080, () => {
console.log('Node listen on port: 8080')
})
- Express listens on port
8080
Conclusion
- If we want to control the file name of the uploaded file, the disk storage engine gives us full control on storing files to disk