我有一个允许用户上传CSV文件的表单,后者使用Superagent对后端的控制器进行POST调用,该控制器解析文件并在我们的表中执行批量插入。我想在前端实现一个进度条,它监听来自控制器的更新,以显示解析/插入的进度。在前端我正在使用React并且正在进行这样的调用:
request.post('/api/uploadFile')
.send(csvFile)
.on('progress', function(e) {
console.log('Percentage done: ', e.percent);
})
.end((err, resp) => {
if (err) {
$("#loading").hide();
console.log("Error in file upload");
console.error(err);
alert("Failed to upload. " + err + "\n (" + err.status + ") " + resp.text);
}
else {
$("#loading").hide();
console.log(resp);
alert("Success. " + resp.text);
return resp;
}
});
}
一旦发送文件,进度事件监听器就会自动显示100%,这是不正确的(发送似乎是即时的,但实际上并不知道从另一端到达了多少,直到有响应)。在后端我有一个像这样的控制器:
@RequestMapping(value="/api/uploadFile", method=RequestMethod.POST)
public @ResponseBody ResponseEntity<String> handleFileUpload(@RequestParam("file") MultipartFile file){
if (!checkCSV(file)) {
return ResponseEntity.status(HttpStatus.UNPROCESSABLE_ENTITY).body("Not CSV");
}
if (file.isEmpty()) {
return ResponseEntity.status(HttpStatus.UNPROCESSABLE_ENTITY).body("File is empty");
}
MySQLAccess db = new MySQLAccess();
File fileToParse = convertToFile(file);
/* Call helper function that parse CSV file & execute batch inserts & creates join tables */
return ResponseEntity.ok("File was uploaded.");
}
我想在我的控制器中交换进度状态(我可以设置),它将更新文件上传所在步骤的前端:解析/批量插入/表创建等。我想这样做因为我的应用程序当前部署在Heroku上,并且我一直在命令请求超时,因为文件上载过程大约需要1分钟,这超过了Heroku为H12请求超时设置的30秒窗口,如果它没有收到单个字节返回给客户端(我假设如果我发回更新它可能会阻止这些超时?)。有没有人有任何关于如何从我的控制器发送更新以在响应被发回之前更新进度的建议?