2013-02-24 27 views
0

我嘗試使用POST請求從node.js發送* .wgt文件(這是有效的* .zip文件)到Wookie服務器在其上運行的其他服務器。我遵循http服務器fs的node.js文檔和兩個其他帖子在stackoverflow(Node.js POST File to Serverhow to upload a file from node.js),但我沒有管理這個工作。Sendindg從* .zip/*。wgt文件到Wookie服務器的nod​​e.js服務器的POST請求

我已經這樣做:

我有一個存儲Node.js的服務器上* .wgt文件。我在節點中創建一個http服務器,準備POST請求到Wookie REST API,獲取帶有fs.createReadStream()的* .zip文件流,然後使用pipe()對其進行流式處理。但我得到了以下錯誤響應:

Error: No file found uploaded to the server. The request sent by the client was syntactically incorect (No file uploaded to server).

這個特殊請求的Wookie服務器API參考如下所示:

POST {wookie}/widgets {file} - Adds a widget to the server. The method echoes the widget metadata in the response.

我的代碼如下:

var http = require('http'); 
var fs = require('fs'); 
var file_name = 'test.wgt'; 

// auth data for access to the wookie server api 
var username = 'java'; 
var password = 'java'; 
var auth = 'Basic ' + new Buffer(username + ':' + password).toString('base64');  

// boundary key for post request    
var boundaryKey = Math.random().toString(16); 
var wookieResponse = ""; 

// take content length of the request body: see https://stackoverflow.com/questions/9943010/node-js-post-file-to-server 
var body_before_file = 
     '--' + boundaryKey + '\r\n' 
     + 'Content-Type: application/octet-stream\r\n' 
     + 'Content-Disposition: form-data; name="file"; filename="'+file_name+'"\r\n' 
     + 'Content-Transfer-Encoding: binary\r\n\r\n'; 
var body_after_file = "--"+boundaryKey+"--\r\n\r\n"; 

fs.stat('./uploads/'+file_name, function(err, file_info) { 
    console.log(Buffer.byteLength(body_before_file) +"+"+ file_info.size +"+"+ Buffer.byteLength(body_after_file)); 

    var content_length = Buffer.byteLength(body_before_file) + 
     file_info.size + 
     Buffer.byteLength(body_after_file); 

    // set content length and other values to the header 
    var header = { 
     'Authorization': auth, 
     'Content-Length': String(content_length), 
     'Accept': '*/*', 
     'Content-Type': 'multipart/form-data; boundary="--'+boundaryKey+'"',//, 
     'Accept-Encoding': 'gzip,deflate,sdch', 
     'Accept-Charset': 'ISO-8859-2,utf-8;q=0.7,*;q=0.3' 
    }; 
    // set request options 
    var options = { 
      host: appOptions.hostWP, 
      port: 8080, 
      path: '/wookie/widgets', 
      method: 'POST', 
      headers: header 
    }; 

    // create http request 
    var requ = http.request(options, function(res) { 
     res.setEncoding('utf8');  
     res.on('data', function (chunk) { 
      wookieResponse = wookieResponse + chunk; 
     }); 
     res.on('end', function (chunk) { 
      wookieResponse = wookieResponse + chunk; 
      console.log(wookieResponse); 
     }) 
    }); 

    // write body_before_file (see above) to the body request 
    requ.write(body_before_file); 

    // prepare createReadStream and pipe it to the request 
    var fileStream = fs.createReadStream('./uploads/'+file_name); 
    fileStream.pipe(requ, {end: false}); 

    // finish request with boundaryKey 
    fileStream.on('end', function() { 
     requ.end('--' + boundaryKey + '--\r\n\r\n'); 
    }); 

    requ.on('error', function(e) { 
     console.log('problem with request: ' + e.message); 
    }); 
}); 

我做錯了,我怎麼能通過來自node.js的POST請求來實現正確的* .wgt/*。zip文件上傳?

乾杯, 米哈爾

回答

2

我取得了哪些問題描述的目標:從node.js的發送POST請求與* .zip文件/ * WGT文件到其他服務器。

我沒有管理與問題中引入的aproach:使用請求模塊一步一步地構建請求。我做了一些研究,發現了intersting node.js模塊:form-data。這個模塊做什麼? Readme.md說:

A module to create readable "multipart/form-data" streams. Can be used to submit forms and file uploads to other web applications.

在部分其中示例,其中列出我發現下面的例子:

var CRLF = '\r\n'; 
var form = new FormData(); 

var options = { 
    header: CRLF + '--' + form.getBoundary() + CRLF + 'X-Custom-Header: 123' + CRLF + CRLF, 
    knownLength: 1 
}; 

form.append('my_buffer', buffer, options); 

form.submit('http://example.com/', function(err, res) { 
    if (err) throw err; 
    console.log('Done'); 
}); 

在上面有一個FormData()對象創建的例子中,數據被附加到表格,然後形成是submited。此外還有一個自定義hedear創建。

我合併我的問題與上面給出的示例代碼提供的代碼,並得到了其解決我的問題代碼:

var formData = require('form-data'); 
var fs = require('fs'); 

var CRLF = '\r\n'; 
var form = new FormData(); 

var options = { 
    header: '--' + form.getBoundary() + 
      CRLF + 'Content-Disposition: form-data; name="file";'+ 
        'filename="bubbles.wgt"'+ 
      CRLF + 'Content-Type: application/octet-stream' + 
      CRLF + CRLF 
    }; 

form.append('file',fs.readFileSync('./uploads/bubbles.wgt'),options); 

form.submit({ 
     host: host, 
     port: '8080', 
     path: '/wookie/widgets', 
     auth: 'java:java' 
     }, function(err, res) { 
      if (err) throw err; 
      console.log('Done'); 
      console.log(res); 
     }); 

我希望這將有助於其他人。

乾杯, Michal