通过节点发送完整的多部分/混合请求的问题

时间:2015-01-19 22:48:09

标签: javascript node.js

我需要POST一个不使用分块的multipart / mixed请求。从我所读到的内容来看,这意味着我必须从 http 中取消请求,而不是使用npm 请求

This post让我开始,但我被困住了。

请求的第一部分是描述文件的基本XML有效负载。第二部分是要发布的文件"。

当我调用request.end()时,我发现POST命中了它所要求的服务器。但是,响应回调不会被击中15-20秒。如果是这样,我会看到以下内容:

客户端在超时期限过去之前未能发送完整的请求。

也许我正在计算内容长度错误,所以服务器在等我吗?

   //Calc size of string in XMLWriter object
    var xmlRequestSize = Buffer.byteLength(dsXml.toString());

    //Calculate Content-Size for each of two parts of a multi-part request
    data = fs.readFileSync("Blood Testing.tde")
    var fileRequestSize = Buffer.byteLength(data.toString());

    console.log(xmlRequestSize);
    console.log(fileRequestSize);  

    //Multi-part boundary
    var boundary = 'zxyzzy123456boundary';

    //Request options
    var postOptions=
        {
            hostname: tableauServer,
            port: 8888, // for proxy
            path: '/api/2.0/sites/' + siteID + '/datasources?overwrite=true',
            method: 'POST',
            headers: {
                'X-Tableau-Auth': adminAuthToken, 
                'Content-Length': xmlRequestSize + fileRequestSize,
                'Content-Type': 'multipart/mixed; boundary=' + boundary

            }
        }


   postCallback = function(response) {
       console.log("Hit callback");
       var str = '';
      //another chunk of data has been recieved, so append it to `str`

      response.on('data', function (chunk) {
        str += chunk;
      });

      //the whole response has been recieved, so we just print it out here
      response.on('end', function () {
        console.log(str);

      });
    }

    var req_post = http.request(postOptions, postCallback);

    //Part 1 metadata
     req_post.write("\r\n--" + boundary + "\r\nContent-Disposition: name='request_payload'\r\nContent-Type: 'text/xml'\r\n\r\n");

     //Part 1 Body
     req_post.write(dsXml.toString());

    //Part 2 metadata
     req_post.write("\r\n--" + boundary + "\r\nname='tableau_datasource'; filename='Blood Testing.tde'\r\nContent-Type: 'application/octet-stream'\r\n\r\n");

    //Part 2 Body
     req_post.write(fs.createReadStream('Blood Testing.tde').toString());


    //Close Boundary
     req_post.write("\r\n--" + boundary + "--\r\n");

     console.log("About to .end()");               
     req_post.end();

    // callback(null);   

    }

如何计算这只小狗和/或其他任何我做错的任何帮助都将不胜感激。

...并且在突破Fiddler后,看起来我想通过request.write添加的东西都没有让它成为INTO请求。提琴手抱怨道:

enter image description here

...如果我查看原始请求,除了标题之外什么都没有。奇。想法?

编辑#2:最终解决方案

// Simple upload of a TDE file < 64MB inline in the request.
var simplePublish = function(callback) {
        //Site ID of your 'REST' site. Lookup with REST API or PGAdmin3                       
        var siteID = '98823511-cfc3-4e24-9790-27e1855fed75';

        //First, build the XML for the POST
        var dsXml = new XMLWriter();
        dsXml.startElement('tsRequest')
                    .startElement('datasource')
                    .writeAttribute('name', 'BloodTesting')
                        .startElement('project')
                            // ID of the Default Project in REST site. Lookup with REST API or PGAdmin3
                            .writeAttribute('id', 'a8a1c0c6-0e49-4243-a271-d49f79c7ccdb')
                        .endElement()
                    .endElement()
                .endElement();
        console.log(dsXml.toString());

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


    form.append('request_payload', dsXml.toString(), {contentType: 'text/xml'});
    form.append('tableau_datasource', fs.createReadStream('Blood Testing.tde'),{contentType: 'application/octet-stream'});

    form.submit(
        {
            host: tableauServer,
            //port: 8888, // for proxy
            path: '/api/2.0/sites/' + siteID + '/datasources?overwrite=true',
            //method: 'POST',
            headers: {
                'X-Tableau-Auth': adminAuthToken, 
                'Content-Type': 'multipart/mixed; boundary=' + form.getBoundary()
            }
        }, function(err, res) {
              if (err) throw err;
             console.log(res.statusCode);
             var str = '';
              //another chunk of data has been recieved, so append it to `str`

              res.on('data', function (chunk) {
                str += chunk;
              });

              //the whole response has been recieved, so we just print it out here
              res.on('end', function () {
                console.log(str);

              });

        });

0 个答案:

没有答案