如何解决未找到请求部分,但在 FormData 中传递并运行两次
我有一个 NodeJS/Express/Node-Fetch 堆栈,它尝试通过从浏览器分段上传的方式接收文件,然后将该请求转发给 Java Spring Boot 服务器。
我的路由片段如下。我已验证文件已上传并且 Multer 插件已保存文件。
两个问题:
- Node/Express 中间件运行两次(我相信只有核心 (req,res,next),而不是电子表格 FileMiddleware.single)
- Spring boot 抱怨我没有传入必需的请求部分“文件”,但是如果您在下面看到,FormData 对象包含它。我怀疑如果我只有一个值并且 @RequestPart 注释上没有标签,它会接受它。
- 我应该使用@RequestPart 还是@RequestParam?
NodeJS/Express 路由片段:
app.post('/bluecost/spreadsheet/upload/*',ensureAuthenticated,function (req,next) {
logger.debug('Route: /bluecost/*: Reached ' + req.originalUrl);
next();
},spreadsheetFileMiddleware.single('file'),(req,next) => {
const url = require('url');
var spreadsheet_host_url = url.parse(config.spreadsheet_server_host,true);
spreadsheet_host_url.pathname = req.originalUrl.substr(0,'/bluecost/spreadsheet/upload/'.length);
var spreadsheet_file_name = req.originalUrl.substr('/bluecost/spreadsheet/upload/'.length);
// spreadsheet_host_url.pathname = spreadsheet_host_url.pathname.replace('/bluecost/','/');
logger.debug('/spreadsheet-upload: Generating token based on proxyReqOpts.user=' + req.user);
var spreadsheet_host_url_string = url.format(spreadsheet_host_url);
logger.info(`@@Route for ${req.originalUrl} Request ${req.method} ${spreadsheet_host_url_string}`);
var accessToken = generateToken(req.user);
/**
* Set bearer token based on code from Sprint-API's lua code
*/
// req.setHeader('Authorization','Bearer ' + accessToken);
logger.debug('Route: /bluecost: adding Authorization: Bearer ' + accessToken);
var newHeaders = req.headers;
newHeaders['Authorization'] = 'Bearer ' + accessToken;
if (!(isMultipartRequest(req) && req.method === 'PUT' || req.method === 'POST')) {
console.log('Expecting multipart file request. Content type or method does not match');
} else {
console.log('@@ detected multipart form');
if (req.body && req.body.length>0) {
var encodedBodyBuffer = new Buffer(req.body);
var encodedBody = encodedBodyBuffer.toString('base64');
console.log('@@ MULTIPART Encoded=' + encodedBody);
console.log('@@ END MULTIPART');
}
var FormData = require('form-data');
console.log('@@ req.file.path='+req.file.path);
const formData = new FormData();
const fs = require('fs');
var testSpreadsheetStream = fs.createReadStream(req.file.path);
formData.append('file',fs.createReadStream(req.file.path));
formData.append('fileName',spreadsheet_file_name);
console.log('req headers=' + JSON.stringify(req.headers));
const options = {
port: spreadsheet_host_url.port,path: spreadsheet_host_url.pathname,method: req.method,headers: req.headers,body: formData,redirect: true,compress: true
};
const fetch = require('node-fetch');
fetch(spreadsheet_host_url_string,options).then(r => {
console.log('@@ spreadsheet send reached fetch result retrieved');
return r.text();
}).then(fetchText => {
console.log('@@ spreadsheet send reached fetch text result retrieved');
/*
// This code complains that headders can't be set after sending to client
res.writeHead(res.statusCode,res.headers);
res.send(fetchText);
*/
// res.body=fetchText;
console.log('@@ fetchText=' + fetchText);
res.status(200).send(fetchText);
next();
}).catch(err => {
console.log('Error on spreadsheet send ' + err);
next(err);
});
}
}
);
Spring Boot 处理程序片段:
@ApiOperation(
value = "Upload spreadsheet data file",notes = "Allows you to upload a single file with each request")
@PostMapping("/spreadsheet/upload/")
public ResponseEntity<HashMap<String,Object>> uploadSpreadsheet(@RequestPart("file") MultipartFile file,@RequestPart("fileName") String filename) {
application.properties 片段是:
spring.http.multipart.enabled=true
application.properties 片段现在:
spring.servlet.multipart.enabled=true
我打开了 Fiddler 并得到了这个拦截:
POST https://localhost:8080/cost/spreadsheet/upload/SSCSpreadsheetUpload-01012020.xlsx HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Content-Length: 278
sec-ch-ua: "Chromium";v="88","Google Chrome";v="88",";Not A Brand";v="99"
Accept: application/json,text/plain,*/*
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/88.0.4324.190 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryVMR7c6jhYiM41kWt
Origin: https://localhost:8080
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://localhost:8080/spreadsheet-upload
Accept-Encoding: gzip,deflate,br
Accept-Language: en-US,en;q=0.9
Cookie: connect.sid=s%3AjbpdjfK0T-.....
------WebKitFormBoundaryVMR7c6jhYiM41kWt
Content-Disposition: form-data; name="file"; filename="SSCSpreadsheetUpload-01012020.xlsx"
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
SmallFile.txt
------WebKitFormBoundaryVMR7c6jhYiM41kWt--
我将 Excel 文件的内容更改为“SmallFile.txt”,只是为了确保文件传递机制正常工作。我觉得可以安全地得出结论,它确实按预期传递了表单数据。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。