如果我发送带有文本选项的 POST 查询,一切正常:
query from front-end:
const request = require("request")
const options = {
method: 'POST',
url: 'http://localhost:4000/user',
headers: form: { data: '12345' }
}
在服务器端(KOA)我可以获取 a.m.query 的解析数据:
ctx.request.method: "POST"
ctx.request.originalUrl: "user"
ctx.request.body.data: "12345"
但是如果我发送带有二进制数据(文件)的 POST 查询:
const fs = require("fs");
const request = require("request");
const options = { method: 'POST',
url: 'http://localhost:4000/user',
headers:
{
'content-type': 'multipart/form-data},
formData:
{ '':
{ value: 'fs.createReadStream("F:\\image.jpg")',
options:
{ filename: 'F:\\image.jpg',
contentType: null }
} } };
我不知道,如何在服务器部分(KOA)上访问此二进制数据(“image.jpg),在 ctx.request 中有任何包含此数据的字段...
您可以使用
busboy
来实现此目的。 我为此写了一个要点,但我将把它和一些评论一起嵌入这里。
让我们创建一个助手,以一种承诺友好的方式解析文件。
// parse.js
import Busboy from 'busboy'
/**
* Parses a single file from a Node request.
*
* @param {http.IncommingRequest} req
* @return {Promise<{ file: Stream, filename: string>}
*/
export default function parse (req) {
return new Promise((resolve, reject) => {
const busboy = new Busboy({
headers: req.headers,
limits: {
files: 1 // allow only a single upload at a time.
}
})
busboy.once('file', _onFile)
busboy.once('error', _onError)
req.pipe(busboy)
function _cleanup () {
busboy.removeListener('file', _onFile)
busboy.removeListener('error', _onError)
}
function _onFile (fieldname, file, filename) {
_cleanup()
resolve({ file, filename })
}
function _onError (err) {
_cleanup()
reject(err)
}
})
}
现在我们需要使用它。假设您要上传到 AWS S3。
import Koa from 'koa'
import parse from './busboy'
import AWS from 'aws-sdk'
const app = new Koa()
const s3 = new AWS.S3({
params: { Bucket: 'myBucket' }
})
// Assuming this is a route handler.
app.use(async (ctx) => {
const { file, filename } = await parse(ctx.req)
// `file` is a Stream. Pass this to S3, Azure Blob Storage or whatever you want.
// `filename` is the file name specified by the client.
const result = await s3.upload({
Key: filename,
Body: file
}).promise()
ctx.body = result
})
为了简洁起见,这是在客户端上使用
axios
上传文件的方法。
// `file` is a DOM File object.
function upload (file) {
const data = new window.FormData()
data.append('file', file, file.name)
return axios.post('/upload', data)
}