2012-12-10 20 views
28

Tôi cố gắng để tải lên một bức ảnh thông qua một yêu cầu POST với request moduleNodejs POST yêu cầu multipart/form-data

Theo readme Tôi chỉ có thể làm được điều này

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

Vấn đề là, điều này không hoạt động. Tôi nhận được một thư trả lời từ máy chủ kiểm tra nói rằng nó đã đổ 0 biến bài đăng.

Tôi đã xác nhận rằng máy chủ đang trong tình trạng làm việc với điều này ít trang 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> 

Vì vậy, câu hỏi là, những gì tôi làm sai với các module theo yêu cầu? Có cách nào tốt hơn để gửi multipart/form-data bằng nút không?

+0

Bạn cũng đang nhập thư viện dữ liệu biểu mẫu chưa? –

+0

Tôi không cần phải, nó được tích hợp vào mô-đun yêu cầu. – giodamelio

+0

Có sự khác biệt trong URL của bạn. Một người đang sử dụng phương thức https và một phương thức khác là http bình thường. Đây có phải là cái gì đó đã được xem xét? –

Trả lời

25

Sau một số nghiên cứu khác, tôi quyết định sử dụng restler module. Nó làm cho việc tải lên nhiều phần thực sự dễ dàng.

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

Đảm bảo câu lệnh sau tại mục nhập var fs = require ('fs'); – webjockey

+1

Lấy kích thước tập tin: var fs = require ('fs'); var fileStats = fs.statSync ('/ myFile.jpg'); var fileSizeInBytes = fileStats ["size"]; console.log (fileStats); console.log (fileSizeInBytes); –

+0

Tôi gặp lỗi nếu kích thước tệp lớn hơn 2 mb. Tôi nên sửa đổi mã gì? – 981

3

Tôi có mã làm việc thực hiện chính xác câu hỏi của bạn, ngoại trừ một ngoại lệ. nội dung tập tin của tôi được nối theo cách này:

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

Để khám phá các tùy chọn tranh luận cuối cùng tôi đã phải đi sâu vào nguồn gốc của form-data. Nhưng điều này mang lại cho tôi một cấu hình làm việc. (Có lẽ đó là những gì bạn đã mất tích, nhưng tất nhiên điều đó sẽ phụ thuộc vào máy chủ.)

13

Vì vậy, tôi chỉ bị làm vật lộn với điều này bản thân mình và đây là những gì tôi đã học:

Nó chỉ ra rằng không phải yêu cầu hoặc biểu mẫu dữ liệu đang đặt tiêu đề độ dài nội dung cho luồng nội dung được tạo.

Dưới đây là vấn đề báo cáo: https://github.com/mikeal/request/issues/316

Giải pháp đăng bởi @lildemon được việc này bằng cách:

  1. Tạo các FormData đối tượng
  2. Bắt đó là chiều dài
  3. Làm theo yêu cầu và thiết lập đối tượng biểu mẫu và tiêu đề nội dung có độ dài rõ ràng

Đây là một phiên bản sửa đổi của các ví dụ của bạn:

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

Điều này thực sự đã giúp tôi. Sau nhiều giờ tìm kiếm tôi mới có được điều này. Cảm ơn. –

2

Tôi cũng đã cố gắng yêu cầu và các module form-data và không thể tải lên một tập tin. Bạn có thể sử dụng superagent hoạt động:

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

điều này có trả lời câu hỏi không? – M4ver1k

+0

superagent dễ sử dụng hơn FormData, trình khôi phục hoặc trục. Loại @/superagent đã lỗi thời. (3.1 thay vì 3.4) – nagylzs

-1

Thử mô-đun yêu cầu. Nó hoạt động giống như bất kỳ yêu cầu đăng bài bình thường nào khác

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

Khi đăng url này lên một url của dịch vụ khác, thuộc tính readStream biến mất khỏi tải trọng và không có sự kiện nào trên yêu cầu được phát hiện trên đầu nhận. Bất kỳ ý tưởng tại sao? –