从浏览器将CSV文件发送到Node.js服务器

7

我正在尝试将用户上传的csv文件从浏览器发送到nodejs服务器进行处理(文件超过50 mb,因此页面变得无响应)。我使用XMLHttpRequest来实现这个目的。我找不到解决方案。非常感谢任何帮助。

Javascript代码

 var csv = document.getElementById('inputFile').files[0];
 var request = new XMLHttpRequest();
 request.open("POST", "/handleFile", true);
 request.setRequestHeader("Content-type", "text/csv");
 request.onreadystatechange = function() {
   if (request.readyState === XMLHttpRequest.DONE && request.status === 200) {
     console.log("yey");
   }
 }

 request.send(csv);

NodeJS 服务器

 var express = require('express')
 var app = express()
 var bodyparser = require('body-parser')

 app.post('/handleFile', function(req, res) {
   console.log(req.body); // getting {} empty object here....
   console.log(req);

   var csv = req.body;
   var lines = csv.split("\n");
   var result = [];
   var headers = lines[0].split("\t");

   for (var i = 1; i < lines.length; i++) {
     var obj = {};
     var currentline = lines[i].split("\t");

     for (var j = 0; j < headers.length; j++) {
       obj[headers[j]] = currentline[j];
     }

     result.push(obj);
   }

   fileData = result;
 });

我做错了什么?是XMLHttpRequest使用不正确吗?还是有其他我没有理解的东西?为什么即使是 post 请求,req.body中也没有数据。或者是否有其他方法从前端将csv/text文件发送到nodejs服务器。
这个问题不是重复的,因为负责解析req.body的中间件body-parser不处理text/csv和multipart/form-data。上面的链接不是正确的解决方案。

1
我认为你应该看一下multer - Sudheesh Singanamalla
@Subhash - 那个链接被描述为“用于处理multipart/form-data的Node.js中间件”。由于OP正在发送text/cvs数据而不是multipart/form-data,那么它如何有所帮助呢? - Quentin
@Quentin 这不会帮助服务器解析数据,它只是在不使页面无响应的情况下将数据发送到服务器。一旦文件完全上传,可以在服务器端异步处理它。这个问题是关于“是否有其他方法从前端向nodejs服务器发送csv /文本文件”,而不是如何在那里解析它。 - Emil S. Jørgensen
@EmilS.Jørgensen,无论我将其切成更小的部分与否,都不会有影响,因为我在服务器端没有收到任何东西。现在我有一个小的演示文件,不应该使页面无响应。 - Subhash
@Subhash - 不要“更改选项”,请使用在重复问题的已接受答案中描述的原始正文选项。 - Quentin
显示剩余10条评论
1个回答

7

所以,在查找后,我发现问题不在我的XMLHttpRequest上。服务器已正常接收请求,但是body-parser无法解析text/csv和multipart/form-data内容类型。以下是解决这个问题的步骤。

  1. In the client/browser-end whenever you are sending a large file to the server, convert it into multipart/form-data . It is the correct way of sending a text/csv/anyfile to the server.

    var csv=document.getElementById('inputFile').files[0];
    var formData=new FormData();
    formData.append("uploadCsv",csv);
    var request = new XMLHttpRequest();
    
     //here you can set the request header to set the content type, this can be avoided.
     //The browser sets the setRequestHeader and other headers by default based on the formData that is being passed in the request.
     request.setRequestHeader("Content-type", "multipart/form-data"); //----(*)
     request.open("POST","/handleFile", true);
    request.onreadystatechange = function (){
        if(request.readyState === XMLHttpRequest.DONE && request.status === 200) {
        console.log("yey");
        }
    }
    
    request.send(formData);
    

这是将http请求发送到nodejs服务器的方法。

  1. 在Node js服务器上:对于application/json或任何其他请求类型,body-parser都可以正常工作。但是对于大型数据和文件,即multipart/form-data,body-parser无法解析req.body。因此,它将返回req.body为{}(空对象)。 在这里阅读有关body-parser的更多信息。

因此,对于这些content-type,您可以使用其他中间件来处理请求。其中一些是multer,multiparty,busboy等。我使用了multer。 以下是代码片段。

    //EXPRESS
    var express = require('express')
    var app = express()

    var config=require('./config.js');
    //multer
    var multer  = require('multer');
    var upload = multer();
    app.post('/handleFile',upload.single('uploadCsv'), function(req, res, next) {
          // req.file is the `uploadCsv` file 
          // req.body will hold the text fields, if there were any 
          console.log(req.file);
          // the buffer here containes your file data in a byte array 
          var csv=req.file.buffer.toString('utf8');
     });

注意:这仍会在nodejs服务器中给您一个错误。 提示:它与(*)行有关。尝试将其删除,看看会发生什么。 谷歌其余部分 ;)


在设置任何头信息之前,应该先打开请求。 - Chase Choi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接