有一个项目,Node(Egg)+ Vue,服务端接口通过Node转发。 服务端新增了一个文件上传表单接口,但是前后端联调的时候怎么都调试不通。
服务端form表单两个字段
type
字符串source
文件通过Postman测试服务端接口,没问题,可以分别通过$_POST
,$_FILES
拿到type
,source
。
那就是前段调用的问题。
前端的写法也是标准写法,所以感觉问题不在web层,而在Node层。
Node层,通过Proxy对请求的header和body做了个性化处理,但是发现没有对multipart做支持。
} else if (ctx.path.indexOf('uploadExcel') !== -1) {
const stream = await ctx.getFileStream();
const fieldsType = stream.fields && stream.fields.type;
let form = new FormData()
form.append('type', fieldsType)
form.append('source', stream)
let opt = parseRequest(options, url, ctx);
// @ts-ignore
opt.data = form
let res = await urllib.request(opt.uri, opt);
ctx.body = res.data;
服务端还是拿不到,通过tcpflow抓包,发现http body是把stream对象作为字符串传递过去了
{"_overheadLength":248,"_valueLength":1,"_valuesToMeasure":[],"writable":false,"readable":true,"dataSize":0,"maxDataSize":2097152,"pauseStreams":true,"_released":false,"_streams":["----------------------------511334654748913548825165\\\\r\\\\nContent-Disposition: form-data; name=\\\\"type\\\\"\\\\r\\\\n\\\\r\\\\n","1",null,"----------------------------511334654748913548825165\\\\r\\\\nContent-Disposition: form-data; name=\\\\"source\\\\"\\\\r\\\\nContent-Type: application/octet-stream\\\\r\\\\n\\\\r\\\\n",{"source":{"_readableState":{"objectMode":false,"highWaterMark":16384,"buffer":{"head":{"data":{"type":"Buffer","data":[49,10,50,10,51,10]},"next":null},"tail":{"data":{"type":"Buffer","data":[49,10,50,10,51,10]},"next":null},"length":1},"length":6,"pipes":null,"pipesCount":0,"flowing":false,"ended":true,"endEmitted":false,"reading":false,"sync":false,"needReadable":false,"emittedReadable":true,"readableListening":false,"resumeScheduled":false,"destroyed":false,"defaultEncoding":"utf8","awaitDrain":0,"readingMore":false,"decoder":null,"encoding":null},"readable":true,"domain":null,"_events":{},"_eventsCount":4,"truncated":false,"fieldname":"source","filename":"test.xlsx","encoding":"7bit","transferEncoding":"7bit","mime":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","mimeType":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","fields":{"type":"1"}},"dataSize":0,"maxDataSize":null,"pauseStream":true,"_maxDataSizeExceeded":false,"_released":false,"_bufferedEvents":[{"0":"pause"}],"_events":{},"_eventsCount":1},null],"_currentStream":null,"_insideLoop":false,"_pendingNext":false,"_boundary":"--------------------------511334654748913548825165"}
opt.stream = form
<https://github.com/node-modules/urllib>
data Object - Data to be sent. Will be stringify automatically.
stream stream.Readable - Stream to be pipe to the remote. If set, data and content will be ignored.