1

Node.js から POST リクエストを含む *.wgt ファイル (有効な *.zip ファイル) を、Wookie Server が実行されている他のサーバーに送信しようとしています。http サーバーfsの node.js ドキュメントと、stackoverflow に関する他の 2 つの投稿 ( Node.js POST File to Servernode.js からファイルをアップロードする方法) に従いましたが、うまくいきませんでした。

私がすでに行ったこと:

node.js サーバーに保存されている *.wgt ファイルがあります。ノードで http サーバーを作成し、Wookie REST API への POST 要求を準備し、*.zip ファイル ストリームを取得して、.zip でストリーミングしfs.createReadStream()ますpipe()。しかし、次のエラー応答が返されます。

エラー: サーバーにアップロードされたファイルが見つかりません。クライアントから送信された要求は構文的に正しくありません (サーバーにファイルがアップロードされていません)。

この特定のリクエストの Wookie Server API リファレンスは次のようになります。

POST {wookie}/widgets {file} - サーバーにウィジェットを追加します。このメソッドは、応答でウィジェット メタデータをエコーし​​ます。

私のコードは次のようになります。

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 ファイルのアップロードを達成するにはどうすればよいですか?

乾杯、ミハル

4

1 に答える 1

2

問題で説明されている目標を達成しました: *.zip/*.wgt ファイルを使用して node.js から POST リクエストを他のサーバーに送信することです。

質問で紹介されたアプローチでは、それを管理できませんでした。リクエストモジュールを使用してリクエストを段階的に構築します。私はいくつかの研究を行い、興味深い node.js モジュールを見つけました: form-data。このモジュールは何をしますか? Readme.md は次のように述べています。

読み取り可能な「multipart/form-data」ストリームを作成するモジュール。フォームの送信や、他の Web アプリケーションへのファイルのアップロードに使用できます。

リストされている例の一部で、次の例を見つけました:

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()オブジェクトが作成され、データがフォームに追加され、フォームが送信されます。さらに、作成されたカスタム 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);
        });

それが他の人に役立つことを願っています。

乾杯、ミハル

于 2013-02-25T19:19:49.697 に答える