2012-12-10 184 views
28

我試圖上傳通過與request module的NodeJS POST請求的multipart/form-data的

POST請求照片按照自述我應該能夠做到這一點

var r = request.post("http://posttestserver.com/post.php", requestCallback) 
var form = r.form() 
form.append("folder_id", "0"); 
form.append("filename", fs.createReadStream(path.join(__dirname, "image.png"))); 

function requestCallback(err, res, body) { 
    console.log(body); 
} 

問題是,這是行不通的。我從測試服務器得到一個答覆,說它傾銷了0個變量。

我已確認該服務器是在這個小的html頁面

<html> 
    <body> 
     <form action="http://posttestserver.com/post.php?dir=example" method="post" enctype="multipart/form-data"> 
      File: <input type="file" name="submitted"> 
      <input type="hidden" name="someParam" value="someValue"/> 
      <input type="submit" value="send"> 
     </form> 
    </body> 
</html> 

所以,問題是工作狀態,我在做什麼錯誤的請求模塊?有沒有更好的方法發送multipart/form-data節點?

+0

您是否也在導入表單數據庫? –

+0

我不需要,它被集成到請求模塊中。 – giodamelio

+0

你的網址有差異。一種是使用https方法,另一種是普通的http。這是否已被考慮? –

回答

25

經過一番更多的研究,我決定使用restler module。它使分段上傳變得非常簡單。

fs.stat("image.jpg", function(err, stats) { 
    restler.post("http://posttestserver.com/post.php", { 
     multipart: true, 
     data: { 
      "folder_id": "0", 
      "filename": restler.file("image.jpg", null, stats.size, null, "image/jpg") 
     } 
    }).on("complete", function(data) { 
     console.log(data); 
    }); 
}); 
+1

請確保以下語句在導入部分var fs = require('fs'); – webjockey

+1

獲取文件大小: var fs = require('fs'); var fileStats = fs.statSync('/ myFile.jpg'); var fileSizeInBytes = fileStats [「size」]; console.log(fileStats); console.log(fileSizeInBytes); –

+0

如果文件大小超過2 MB,則出現錯誤。我應該在代碼中修改什麼? – 981

3

我的工作代碼完全符合您的問題所在,只有一個例外。我的文件內容被附加這樣:

form.append('file', new Buffer(...), 
    {contentType: 'image/jpeg', filename: 'x.jpg'}); 

要發現最後一個參數選項,我不得不向下鑽取的form-data源。但是這給了我一個工作配置。 (也許是你錯過了什麼,但當然這將取決於在服務器上。)

13

所以我只能做這個摔跤我,這裏是我學到了什麼:

事實證明,無論是要求或表單數據正在爲生成的主體流設置內容長度標題。

以下是報告的問題:https://github.com/mikeal/request/issues/316

發表@lildemon該解決方案通過獲得解決此:

  1. 產生FORMDATA對象
  2. 獲取它的長度
  3. 發出請求和設置表單對象和內容長度頭明確

這裏就是你們的榜樣的修改版本:

var request = require('request'); 
var FormData = require('form-data'); 

var form = new FormData(); 
form.append("folder_id", "0"); 
form.append("filename", fs.createReadStream(path.join(__dirname, "image.png"))); 

form.getLength(function(err, length){ 
    if (err) { 
    return requestCallback(err); 
    } 

    var r = request.post("http://posttestserver.com/post.php", requestCallback); 
    r._form = form;  
    r.setHeader('content-length', length); 

}); 

function requestCallback(err, res, body) { 
    console.log(body); 
} 
+0

這真的幫了我。經過長時間的搜索,我剛剛得到了這個。謝謝。 –

2

我想也請求和表單數據模塊和無法上傳文件。 你可以使用superagent哪個作品:

http://visionmedia.github.io/superagent/#multipart-requests

var request = require('superagent'); 
var agent1 = request.agent(); 
agent1.post('url/fileUpload') 
     .attach('file',__dirname + "/test.png") 
     .end(function(err, res) { 
      if (err) { 
       console.log(err) 
      } 
     }); 
+0

這是回答這個問題嗎? – M4ver1k

+0

superagent比FormData,restler或axios更容易使用。雖然@ type/superagent已經過時了。 (3.1而不是3.4) – nagylzs

-1

嘗試請求模塊。它的工作方式與其他任何正常的發佈請求一樣

var jsonUpload = { }; 
var formData = { 
    'file': fs.createReadStream(fileName), 
    'jsonUpload': JSON.stringify(jsonUpload) 
}; 
var uploadOptions = { 
    "url": "https://upload/url", 
    "method": "POST", 
    "headers": { 
     "Authorization": "Bearer " + accessToken 
    }, 
    "formData": formData 
} 
var req = request(uploadOptions, function(err, resp, body) { 
    if (err) { 
     console.log('Error ', err); 
    } else { 
     console.log('upload successful', body) 
    } 
}); 
+0

將此內容發佈到其他服務的url時,readStream屬性從有效內容中消失,並且在接收端沒有檢測到請求上的事件。任何想法爲什麼? –