小程式:Form上傳檔案到Node.js的Express伺服器

彙整項目

  1. 使用HTML form的2種post方法上傳檔案
  2. 使用javascript以put方法上傳檔案
  3. 針對表單上傳對應的伺服器端寫法
  4. 各種上傳對應的CURL指令(見註解)


上code
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const crypto = require('crypto');
const multer = require('multer');
const upload = multer();
app.use(bodyParser.urlencoded({ extended: true }));
// app.use(express.urlencoded()); // deprecated
app.get('/', (req, res) => {
res.send(`
POST:
<form method="POST" action="/post">
<input type="text" name="fieldName" value="name">
<input type="file" name="uploadFile">
<input type="file" name="uploadFile2">
<input type="submit">
</form>
POST form-urlencoded:
<form method="POST" action="/urlencoded" enctype="application/x-www-form-urlencoded">
<input type="text" name="fieldName" value="name">
<input type="file" name="uploadFile">
<input type="file" name="uploadFile2">
<input type="submit">
</form>
POST form-data:
<form method="POST" action="/formdata" enctype="multipart/form-data">
<input type="text" name="fieldName" value="name">
<input type="file" name="uploadFile">
<input type="file" name="uploadFile2">
<input type="submit">
</form>
PUT file:
<form class="put-form">
<input type="file" name="uploadFile" multiple>
<input type="submit">
</form>
<script src="postForm.js"></script>
`);
});
// script for put form
// https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data
app.get('/postForm.js', function (req, res) {
res.type('text/javascript').send(`
var putForm = document.querySelector('form.put-form')
putForm.addEventListener('submit', submitPutForm)
function submitPutForm(e) {
e.preventDefault()
var files = e.target.elements[0].files;
for (var i = 0 ; i < files.length ; ++ i) {
openFile(files[i],
function (err, file) {
if (err) return console.error(err)
putBlob(file.name, file.data,
function (err, rsp) {
if (err) return console.error(err)
appendText(rsp);
}
)
}
)
}
e.target.reset();
}
function appendText(text, root) {
if (!root) root = document.body
var p = document.createElement('p')
p.textContent = text
root.appendChild(p)
}
function openFile(file, cb) {
var r = new FileReader()
r.onload = function () { cb(null, {name: file.name, data: r.result}) }
r.onerror = function (error) { cb(error) }
r.readAsArrayBuffer(file)
}
function putBlob(name, blob, cb) {
var r = new XMLHttpRequest()
r.onerror = function (err) { cb(err) }
r.open("PUT", "/put/" + name)
r.onreadystatechange = function () {
if (r.readyState != 4) return
if (r.status != 200) return cb('response status != 200,' + r.status)
cb(null, r.responseText)
}
r.send(blob)
}
`);
});
// the default post is urlencoded
app.post('/post', function (req, res) {
res.send(req.path + JSON.stringify(req.body));
});
// curl -d fieldName=name -d uploadFile="Screenshot from 2021-09-30 14-45-46.png" http://localhost:3000/urlencoded
app.post('/urlencoded', function (req, res) {
res.send(req.path + JSON.stringify(req.body));
});
function getInfoFromData(name, data) {
return {
name: name,
size: data.length,
md5: crypto.createHash('md5').update(data).digest('hex'),
sha1: crypto.createHash('sha1').update(data).digest('hex'),
sha256: crypto.createHash('sha256').update(data).digest('hex'),
}
}
// curl -F fieldName=name -F uploadFile=@"Screenshot from 2021-09-30 14-45-46.png" http://localhost:3000/formdata
app.post('/formdata', upload.any(), function (req, res) {
res.send(req.path +
JSON.stringify(req.body) +
JSON.stringify(req.files.map(f => getInfoFromData(f.originalname, f.buffer)))
);
});
// curl -T "Screenshot from 2021-09-30 14-45-46.png" http://localhost:3000/put/
// https://nodejs.dev/learn/get-http-request-body-data-using-nodejs
app.put('/put/:filename', async function (req, res) {
let filename = req.params.filename;
let buffers = [];
for await (const chunk of req) buffers.push(chunk);
let data = Buffer.concat(buffers);
res.send(req.path + JSON.stringify(getInfoFromData(filename, data)));
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log('Port:', PORT));
view raw index.js hosted with ❤ by GitHub
{
"scripts": {
"start": "node index.js"
},
"dependencies": {
"body-parser": "^1.19.0",
"crypto": "^1.0.1",
"express": "^4.17.1",
"multer": "^1.4.3"
}
}
view raw package.json hosted with ❤ by GitHub

留言