通过AJAX将Node上传到Heroku - Node / Express

时间:2013-11-21 22:14:34

标签: node.js file-upload express

我有一个数据库,我希望用户能够使用CSV文件进行更新。我正在尝试使用Postgres COPY函数来执行此操作但尚未使用它。

HTML:

<h2>Mass Update</h2>
  <form enctype="multipart/form-data" id="mass">
    <input type="file" id="file" name="upload"/><br/>
    Replace <input type="checkbox" name="replace"/>
  </form>
<button id="trigger-mass">Submit</button>

的jQuery

$('#trigger-mass').on('click', function(){
var fd = new FormData(document.getElementById('mass'));
$.ajax({
    url: base + table,
    processData:false,
    data:fd,
    type:'POST'
});

节点

index.js

 app.use('/', express.static(__dirname + '/static'));
 app.use(express.bodyParser({uploadDir:__dirname +'/static/tmp', keepExtensions:true}));

这似乎不是最佳做法,但在我的情况下可以,因为我希望这些上传可供下载。如果Error:ENOENT open"..."目录在tmp目录之外,我就会收到static

routes.js

 // Clear table and refill with data
 app.post('/data/:table', auth, function(req, res) {
    var oMsg = quickRes(res, req);
    console.log('REQ DATA')
    console.log(req.body);
    console.log(req.files);
...// Here is where I would issue the COPY command through pg
 });

不幸的是,req.files我没有看到任何内容。我也试过直接在AJAX中上传文件data:document.getElementById('file').files[0]无济于事。有什么建议吗?

2 个答案:

答案 0 :(得分:2)

您需要在contentType中明确将false设置为$.ajax()

$.ajax({
  url         : base + table,
  processData : false,
  contentType : false, // <-- required
  data        : fd,
  type        : 'POST'
});

否则,jQuery会将其设置为application/x-www-form-urlencoded; charset=UTF-8,这不适合文件上传。

答案 1 :(得分:1)

我们可以看一下你所包含的中间件以及你正在使用的快递版本吗? express.multipart将在下一版本中弃用,因此您必须使用替代解决方案。到目前为止,普遍的共识是使用connect-busboy npm包作为文件上传的中间件。

示例index.js:

app.use(express.json()); // These replace the bodyParse middleware due to the tmp folder vulnerability
app.use(express.urlencoded());
app.use(busboy());

app.post('/data/:table', auth, function (req, res) {
    var fstream;
    req.pipe(req.busboy);
    req.busboy.on('file', function (fieldname, file, filename) {
        fstream = fs.createWriteStream(__dirname + '/tmp/' + filename);
        file.pipe(fstream);
        fstream.on('close', function () {
            res.redirect('/'); // Or wherever you want to go next
        });
    });
});

包含的节点包可以是expressfsconnect-busboy。请参阅此Github Issue以确认multipart的弃用。