2015-11-27 55 views
0

今天我添加了將照片上傳到我正在工作的網站的功能。該站點內建於Express node.js,我正在使用請求npm模塊上傳。Node.js - 爲請求創建表單與從request.post獲取表單之間的區別?

我不斷收到錯誤信息:「(#324)需要上傳文件」。我認爲這與我試圖上傳的照片文件有關,所以我會嘗試將其轉換爲base64,更改標題,手動創建POST請求等的不同變體。

我最終嘗試了整個代碼一個響應,令我驚訝的是,它的工作,即使圖像數據只是從fs.createReadStream(req.file.path),我曾嘗試過很多次。

我發現不同之處在於我將表單數據添加到我的請求中。最初,我將它定義爲內聯:

request({ 
     url: 'https://graph.facebook.com/me/photos?access_token=' + req.user.facebook.token, 
     method: "POST", 
     form: { 
      source: fs.createReadStream(req.file.path), 
      message: req.body.message 
     } 
    }, function(error, response, body) { 
     var bodyJSON = JSON.parse(body); 
     if(bodyJSON.error) { 
      console.log(bodyJSON.error.message); 
     } 
    }); 

這不斷給我提到前面提到的錯誤。我發現的代碼看起來有點不同。

serverRequest = request.post('https://graph.facebook.com/me/photos?access_token=' + req.user.facebook.token, function(err, res, body) { 
    var bodyJSON = JSON.parse(body); 
    if(bodyJSON.error) { 
      console.log(bodyJSON.error.message); 
    } 
}); 

form = serverRequest.form() 
// append a normal literal text field ... 
form.append('message', req.body.message); 

// append a file field by streaming a file from disk ... 
form.append('source', fs.createReadStream(req.file.path)); 

This works。所以我決定比較兩個不同的表單對象。它們很大,所以我把它們放在Pastebin上。第一個可以看到here和第二個here。有很大的差異。

現在我想知道兩件事情:

  1. 爲什麼兩種不同的形式,DATAS產生的?兩種創建/附加方法的區別是什麼?
  2. 如何在方法1中的請求中追加表單?發佈請求何時實際發生?我假設它在request.post(..)上做了,但是我可以在表單數據發佈之前將其附加到表單數據中。

編輯:回答過的問題下面 問題是由MSCDEX回答。這裏是我現在用於請求的代碼,以防其他人需要它。

request.post(
    { 
     url: 'https://graph.facebook.com/me/photos?access_token=' + authToken, 
     formData: { 
      message: message, 
      source: fs.createReadStream(imageFile.path) 
     } 
    }, function(err, res, body) { 
     var bodyJSON = JSON.parse(body); 
     if(bodyJSON.error) { 
      console.log(bodyJSON.error.message); 
     } 
    } 
); 

回答

1

request documentation解釋了區別。第一種形式是提交類型爲application/x-www-form-urlencoded的請求,而第二種形式是提交multipart/form-data類型的請求。

(二進制)文件通常不能與application/x-www-form-urlencoded請求中提交,所以multipart/form-data通常是用來代替(雖然有些網絡服務可能允許您通過PUT請求提交一個文件,其中請求的內容是原始文件內容)。

HTTP請求在request()時間不會立即發送,因爲它是異步的,並且需要時間來執行DNS查找,設置用於發出HTTP請求的TCP連接等。因此,在那段時間內,您需要時間可能會在表單中追加更多字段(假設request在事件循環的下一個滴答聲之後不會人爲地阻止您這樣做),但最好一次性添加它們以保證安全。

+0

非常感謝!我閱讀了文檔,但不知何故錯過了表單部分的標題。我將更改我的代碼以傳入'multipart/form-data',而不是在後面添加它。還要感謝解釋HTTP請求背後的過程,這很有道理。 –

+0

我已將新的即將安全的代碼添加到原始答案中。我檢查了,它的工作原理。 –

相關問題