node做中间层如何进行文件上传
如今越来越多的前端项目加入了node做中间层, 进行一些请求的拦截,转发等,但是在进行ajax进行文件上传的时候比如无法直接获取客户端传递过来的formdata数据。node层请求库我使用的是node-fetch。
需要安装以下库:
npm install --save node-fetch // node层请求库
npm install --save form-data
npm install --saveconnect-multiparty // 文件上传解析
代码部分
```路由部分
```css
import asyncRouter from '../helpers/asyncRouter'
const router = asyncRouter();
import multipart from 'connect-multiparty'
const multipartMiddleware = multipart()
const fillPath = require('path')
module.exports = (app) => {
app.use('/app-live', router);
};
router.all('/*', multipartMiddleware,async(req, res, next) => {
let path = req._parsedUrl.path,
method = req.method,
args = method === 'POST' ? req.body : req.query;
let responseData = {}
if (req.headers['content-type'] && req.headers['content-type'].includes('multipart/form-data')){
responseData = await req.api(path, method, { body:req.files.file })
} else if ( req.path === '/download'){
path = req.path
responseData = await req.api(path, method, { body: args})
} else {
console.log(path);
responseData = await req.api(path, method, { body: args});
}
responseData.ServerDate = new Date().getTime();
return res.json(responseData);
});
```handlebars
import fetch from 'node-fetch' // 网络请求库
import settings from '../config'; // 获取请求baseUrl路径
import fs from 'fs'
import path from 'path'
import FormData from 'form-data' // 文件上传formData对象
async function request(opts, {}) {
const method = opts.method || 'GET';
opts.headers = opts.headers || {};
opts.headers.Authorization = opts.headers.Authorization;
if (!_.has(opts.headers, 'Content-Type')) {
opts.headers['Content-Type'] = 'application/json';
}
const body = opts.body || {};
if (!body.Token) {
body.Token = opts.token;
}
// 普通请求
const requestOptions = function() {
const header = Object.assign({},opts.headers)
return new Promise(async (resolve, reject) => {
// post请求配置
const optionsPost = {
timeout: 100000,
headers: header,
method,
body: method === "POST" ? JSON.stringify(body) : {},
}
// get强求配置
const optionsGet = {
timeout: 100000,
headers: header,
method
}
resolve( method === "POST" ? optionsPost: optionsGet )
})
};
// 文件上传
const requestFormDataOptions = function() {
const {path:filePath, originalFilename } = body
const newPath = path.join(path.dirname(filePath), originalFilename)
const header = Object.assign({},opts.headers)
delete header['Content-Type'] // node-fetach 上传文件不需要请求Content-Type
return new Promise((resolve, reject) => {
fs.rename(filePath, newPath, async function (err) {
if(err) return
const file = fs.createReadStream(newPath)
const form = new FormData()
form.append('file', file)
resolve({
timeout: 100000,
headers:header,
method,
body: form
})
})
})
};
// 获取配置参数
async function getOptions() {
return opts.headers['Content-Type'].indexOf('multipart/form-data') === -1 ? await requestOptions() : await requestFormDataOptions()
}
try {
// 普通请求
const reqTimeCurrent = new Date()
const response = await fetch(settings.BASE_URL + opts.path, await getOptions())
if (response.status === 204) {
return { deleted: true, url: settings.BASE_URL + opts.path};
}
const responseCopy = response
return {
requestUrl: settings.BASE_URL + opts.path,
requestParams: body,
...await response.json()
}
} catch (err) {
return {
requestUrl: settings.BASE_URL + opts.path,
requestParams: body,
...err
}
}
}