当我们需要在前后端进行文件上传时,可以使用form表单来实现。而如果使用nodejs进行模拟上传,可以通过如下步骤实现:
1. 安装依赖包
首先需要安装 http
, fs
, path
, formidable
等依赖包,其中 formidable
是一个流行的上传文件解析库。
可以通过 npm 安装:
npm install http fs path formidable
2. 创建一组表单
为了模拟文件上传,需要创建一个表单,包含一个文件域:
<form action="/upload" enctype="multipart/form-data" method="post">
<input type="file" name="upload">
<input type="submit" value="Upload File">
</form>
其中 enctype="multipart/form-data"
是必须的,因为这是表单数据类型,可以用于上传文件。
3. 创建服务器
我们需要创建一个服务器来接收上传的文件。下面是一个简单的例子:
const http = require('http');
const fs = require('fs');
const path = require('path');
const formidable = require('formidable');
const server = http.createServer((req, res) => {
if (req.url == '/upload' && req.method.toLowerCase() == 'post') {
const form = new formidable.IncomingForm();
form.parse(req, (err, fields, files) => {
if (err) {
console.log(`Error: ${err}`);
return;
}
const oldPath = files.upload.path;
const newPath = path.join(__dirname, 'uploads', files.upload.name);
fs.rename(oldPath, newPath, (err) => {
if (err) {
console.log(`Error: ${err}`);
return;
}
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(`<h1>Uploaded file: ${files.upload.name}</h1>`);
});
});
} else {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(`
<form action="/upload" enctype="multipart/form-data" method="post">
<input type="file" name="upload">
<input type="submit" value="Upload File">
</form>
`);
}
});
server.listen(8080, () => {
console.log('Server started on port 8080');
});
其中,通过验证 req.url
和 req.method
,可以判断请求类型和请求地址。如果请求是 /upload
,则使用 formidable
解析请求,取得表单里的文件。然后将文件存储到服务器上,最后将结果返回并结束响应。
如果请求不是 /upload
,则返回表单。
4. 测试上传
在浏览器中打开 http://localhost:8080/
,选择一个文件并点击 "Upload File",就可以上传并保存文件到服务器上。
示例1:上传文件到七牛云
以下是一个将文件上传到七牛云的例子,通过 qiniu
包可以轻松地将上传的文件传输到该云空间:
const http = require('http');
const fs = require('fs');
const path = require('path');
const formidable = require('formidable');
const qiniu = require('qiniu');
// 需要填写你的 Access Key 和 Secret Key
const accessKey = 'yourAccessKey';
const secretKey = 'yourSecretKey';
const mac = new qiniu.auth.digest.Mac(accessKey, secretKey);
const options = {
scope: 'your-bucket-name', // 云空间名称
};
const putPolicy = new qiniu.rs.PutPolicy(options);
const uploadToken = putPolicy.uploadToken(mac);
const server = http.createServer((req, res) => {
if (req.url == '/upload' && req.method.toLowerCase() == 'post') {
const form = new formidable.IncomingForm();
form.parse(req, (err, fields, files) => {
if (err) {
console.log(`Error: ${err}`);
return;
}
const uploadFile = files.upload.path;
const key = files.upload.name;
// 创建上传凭证
const formUploader = new qiniu.form_up.FormUploader();
const putExtra = new qiniu.form_up.PutExtra();
// 文件上传
formUploader.putFile(uploadToken, key, uploadFile, putExtra, function(respErr,
respBody, respInfo) {
if (respErr) {
throw respErr;
}
if (respInfo.statusCode == 200) {
// 上传成功
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(`<h1>Uploaded file: ${files.upload.name}</h1>`);
} else {
console.log(respInfo.statusCode);
console.log(respBody);
}
});
});
} else {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(`
<form action="/upload" enctype="multipart/form-data" method="post">
<input type="file" name="upload">
<input type="submit" value="Upload File">
</form>
`);
}
});
server.listen(8080, () => {
console.log('Server started on port 8080');
});
示例2:上传至本地目录
以下是一个将上传的文件保存到本地目录中的例子,所上传的文件都会保存到 uploads
目录中:
const http = require('http');
const fs = require('fs');
const path = require('path');
const formidable = require('formidable');
const server = http.createServer((req, res) => {
if (req.url == '/upload' && req.method.toLowerCase() == 'post') {
const form = new formidable.IncomingForm();
form.parse(req, (err, fields, files) => {
if (err) {
console.log(`Error: ${err}`);
return;
}
const oldPath = files.upload.path;
const newPath = path.join(__dirname, 'uploads', files.upload.name);
fs.rename(oldPath, newPath, (err) => {
if (err) {
console.log(`Error: ${err}`);
return;
}
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(`<h1>Uploaded file: ${files.upload.name}</h1>`);
});
});
} else {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(`
<form action="/upload" enctype="multipart/form-data" method="post">
<input type="file" name="upload">
<input type="submit" value="Upload File">
</form>
`);
}
});
server.listen(8080, () => {
console.log('Server started on port 8080');
});
以上两个例子只是上传文件的方式不同而已,其余代码基本相同。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:nodejs 实现模拟form表单上传文件 - Python技术站