node上传文件到服务端
前言:由于工作要求,需要写个文件上传的接口。之前接触的较少,都是使用现成的接口,自己写接口时却是遇到了难点。该项目是在vue、koa基础上搭建的,关于路由及其他相关知识,可查看其他文章。现将自己的理解写下了,方便日后差异。如有不当地方,还请指正。前端:htmlhtml结构可以写的很简单,一个input标签就足够。代码如下:<input type="file" id
前言:
由于工作要求,需要写个文件上传的接口。之前接触的较少,都是使用现成的接口,自己写接口时却是遇到了难点。
该项目是在vue、koa基础上搭建的,关于路由及其他相关知识,可查看其他文章。
现将自己的理解写下了,方便日后查阅。如有不当地方,还请指正。
前端:
html
html结构可以写的很简单,一个input标签就足够。代码如下:
<input type="file" id="upload__input" @change="uploadFile" accept="" multiple>
js:
js主要处理input文件变化后请求接口,并传参数。
需要注意的是,参数不像表单那样符合键值对的要求,需要使用formData的格式传递。代码如下:
uploadFile (e) {
var fileValue = document.querySelector('#el-upload__input')
this.srcOthers = fileValue.files[0];
var formData = new FormData();
formData.append('file', this.srcOthers);
this.$http.post(this.rootUrl + "postsTxtFile/",formData)
.then((data) => {
console.log(data)
})
.catch((err) => {
console.log(err, 'error');
});
}
代码中核心是声明formData变量,将input的files变量传递进去。可以模拟表单的形式形成键值对,用于异步上传二进制文件。
后端:
后端在拿到参数后,参数形式如下:
{
"method": "POST",
"url": "/api/postsTxtFile/",
"header": {
"accept-language": "zh-CN,zh;q=0.9",
"accept-encoding": "gzip, deflate, br",
"referer": "http://localhost:8080/pageCompare",
"content-type": "multipart/form-data; boundary=----WebKitFormBoundaryKdkJ1bBxZAeKZ1sS",
"user-agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.6726.400 QQBrowser/10.2.2265.400",
"origin": "http://localhost:8080",
"accept": "application/json, text/plain, */*",
"content-length": "7140",
"connection": "close",
"host": "localhost:4000"
}
}
参数中并无法取到二进制文件的内容,因此需要将传递的参数解析为指定形式。在此,需要介绍使用中间件进行传递参数的解析。
因为传递的文件类型为multipart/form-data类型,可使用connect-multiparty等中间件进行转换,本项目中使用的是koa-body进行数据格式的转换。
Koa-body
安装
$ npm install koa-body
使用
如官网所示:
示例中index.js中引入koa之后,使用app.use的方式使用。如下:
const koa = require('koa');
const koaBody = require('koa-body');
// 中间件
app.use(koaBody({
jsonLimit: '20mb',
multipart: true
}));
代码中KoaBody函数传递了两个参数,用于限制json的大小以及设置参数的类型为multipart类型。
另一种调用方式是在接口的router时使用,例如:
import Router from 'koa-router';
import koaBody from 'koa-body';
import postsTxtFile from '../application/postsTxtFile'
export default function () {
const router = Router();
router.prefix('/api');
router.post('/postsTxtFile/', koaBody(
{
jsonLimit: '20mb',
multipart: true
}
),
async (ctx) => {
// => POST body
ctx.body = await postsTxtFile(ctx.request);
// let para = ctx.request;
// let res = await postsTxtFile(para);
// ctx.body = res;
});
return router.routes();
}
代码中,在声明postsTxtFile接口时,调用KoaBody函数,限制了json数据大小以及数据类型为multipart。而后调用postsTxtFile函数,返回处理后的信息。
KoaBody处理后的请求files字段格式如下:
"para": {
"file": {
"size": 287,
"path": "C:\\Users\\guojiangwei\\AppData\\Local\\Temp\\upload_30e4bc4b5cd52550160803d9f2f77904",
"name": "报告解读静态页面.txt",
"type": "text/plain",
"mtime": "2018-11-27T07:57:56.510Z"
}
}
postsTxtFile.js
处理请求的接口函数的代码如下:
import fs from 'fs';
async function main(para) {
let res = {};
if (para && para.files) {
// res = {
// data: para.files.file.name
// }
// 获得文件名
var filename = para.files.file.name;
// 复制文件到指定路径
var targetPath = 'src/uploadText/' + filename;
// 复制文件流
fs.createReadStream(para.files.file.path).pipe(fs.createWriteStream(targetPath));
// 响应ajax请求,告诉它文件上传成功
res = { code: 200, data: { result: 'success' } };
return res;
} else {
return {
code: -1,
result: 'no files'
};
}
}
export default main;
代码中获取了请求中的files的内容,并保存到指定目录中。
至此由前端上传文件到node后端保存文件的代码及流程基本完成。只是个人整理总结的内容,还请各位大佬指正。
更多推荐
所有评论(0)