2013-11-21 42 views
0

我有一個數據庫,我希望用戶能夠使用CSV文件進行更新。我試圖使用Postgres COPY函數來做到這一點,但沒有得到它的工作。通過AJAX將CSV上傳到Heroku - Node/Express

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})); 

這似乎不是最好的做法,但它是在我的情況確定因爲我希望這些上傳是可用的可以下載。如果tmp目錄位於static目錄之外,我正在收到Error:ENOENT open"..."

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

您需要在$.ajax()明確設置contentTypefalse

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

否則,jQuery將其設置爲application/x-www-form-urlencoded; charset=UTF-8,這是不恰當的文件上傳。

+0

這是問題的一部分。當bodyParser試圖將文件存儲在'tmp'中時,我還得到了'Error:ENOENT open「...」'。我在'static'目錄下面加了'tmp'目錄,它工作正常。所以這也是我的文件系統的權限問題。非常感謝。 –

+0

此外,[此答案](http://stackoverflow.com/a/8758614/1149459)可能會對其他人有所幫助。 –

1

我們可以看看您所包含的中間件以及您使用的是什麼版本的Express? express.multipart將在下一個版本中被棄用,因此您必須使用替代解決方案。目前普遍的共識是使用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 
     }); 
    }); 
}); 

包括節點的包將是expressfs,和connect-busboy。請參閱此Github Issue以確認multipart的棄用。

+0

這個問題並不說'bodyParser'將被棄用,它表示['bodyParser'的'multipart'部分將會從它移除](https://github.com/visionmedia/express/issues/ 1793#issuecomment-27016607)。 – robertklep

+0

真的,我會編輯我答案的那一部分。 – Deif

+0

我在Express 3.1上,並且使用上述建議來確保它正常工作。很好的機會,我永遠不會升級BC這是一個短期API我正在建設。但這是否意味着所有表單上傳表達將來都必須使用另一個插件? –