如何将zip文件编码为multipart / form-data的一部分

时间:2017-07-26 22:54:31

标签: node.js encoding zip multipartform-data slack

tldr我在将zip文件作为multipart / form-data请求体的一部分发送时遇到编码问题。请帮助:/

我正在开发一个能够将zip文件上传到Slack的机器人(通过他们的文件api),但我遇到了一些我认为与编码有关的问题。

所以,我正在创建我的请求主体,如下所示:

var form_string = "\n--abcdefghijklmnop\nContent-Disposition: form-data; filename=\"" + filename + "\"; name=\"file\";\nContent-Type:application/octet-stream;\nContent-Transfer-Encoding:base64;\n\n" + data;
form_string += "\n--abcdefghijklmnop\nContent-Disposition: form-data; name=\"token\";\n\n" + token;
form_string += "\n--abcdefghijklmnop\nContent-Disposition: form-data; name=\"filetype\";\n\n" + filetype;
form_string += "\n--abcdefghijklmnop\nContent-Disposition: form-data; name=\"filename\";\n\n" + filename;
form_string += "\n--abcdefghijklmnop\nContent-Disposition: form-data; name=\"channels\";\n\n" + channel;
form_string += "\n--abcdefghijklmnop\nContent-Disposition: form-data; name=\"title\";\n\n" + title;
form_string += "\n--abcdefghijklmnop--";

var form = Buffer.from(form_string, "utf8");

var headers = {
  "Content-Type": "multipart/form-data; boundary=abcdefghijklmnop",
  "Content-Length": form.length,
  "Authorization": "Bearer ....."
};
var options = {
  "headers": headers,
  "body": form 
};
// using the sync-request node module. 
var res = request("POST", url, options);

var res = request("POST", url, options);

(我也尝试了application/zipapplication/x-zip-compressed。我也尝试了二进制和base64内容传输编码。)

(如果你想知道,我需要制作同步的http请求......)

我创建了一个非常小的zip文件作为测试。它的base64编码如下:

UEsDBAoAAAAAAAqR+UoAAAAAAAAAAAAAAAAIABwAdGlueXppcC9VVAkAA1PBd1mDwXdZdXgLAAEE9QEAAAQUAAAAUEsDBAoAAAAAAAuR+Up6em/tAwAAAAMAAAAQABwAdGlueXppcC90aW55LnR4dFVUCQADVsF3WVzBd1l1eAsAAQT1AQAABBQAAABoaQpQSwECHgMKAAAAAAAKkflKAAAAAAAAAAAAAAAACAAYAAAAAAAAABAA7UEAAAAAdGlueXppcC9VVAUAA1PBd1l1eAsAAQT1AQAABBQAAABQSwECHgMKAAAAAAALkflKenpv7QMAAAADAAAAEAAYAAAAAAABAAAApIFCAAAAdGlueXppcC90aW55LnR4dFVUBQADVsF3WXV4CwABBPUBAAAEFAAAAFBLBQYAAAAAAgACAKQAAACPAAAAAAA=

我从Slack得到的东西似乎与原来的相似......也许......

UEsDBAoAAAAAAArCkcO5SgAAAAAAAAAAAAAAAAgAHAB0aW55emlwL1VUCQADU8OBd1nCg8OBd1l1eAsAAQTDtQEAAAQUAAAAUEsDBAoAAAAAAAvCkcO5Snp6b8OtAwAAAAMAAAAQABwAdGlueXppcC90aW55LnR4dFVUCQADVsOBd1lcw4F3WXV4CwABBMO1AQAABBQAAABoaQpQSwECHgMKAAAAAAAKwpHDuUoAAAAAAAAAAAAAAAAIABgAAAAAAAAAEADDrUEAAAAAdGlueXppcC9VVAUAA1PDgXdZdXgLAAEEw7UBAAAEFAAAAFBLAQIeAwoAAAAAAAvCkcO5Snp6b8OtAwAAAAMAAAAQABgAAAAAAAEAAADCpMKBQgAAAHRpbnl6aXAvdGlueS50eHRVVAUAA1bDgXdZdXgLAAEEw7UBAAAEFAAAAFBLBQYAAAAAAgACAMKkAAAAwo8AAAAAAA==

有人可以解释这里的编码是什么以及如何正确地将文件上传到Slack?谢谢!

1 个答案:

答案 0 :(得分:0)

如何关注示例脚本?这种情况有两种模式。

示例脚本1:

为此,我修改了你正在尝试的方法。您可以通过转换为字节数组来上载zip文件,如下所示。首先,它构建form-data。它使用boundary添加转换为字节数组的zip文件和Buffer.concat()。这在请求中用作正文。

var fs = require('fs');
var request = require('request');
var upfile = 'sample.zip';
fs.readFile(upfile, function(err, content){
    if(err){
        console.error(err);
    }
    var token = '### access token ###';
    var filetype = 'zip';
    var filename = 'samplefilename';
    var channel = 'sample';
    var title = 'sampletitle';
    var formString = "\n--abcdefghijklmnop\nContent-Disposition: form-data; name=\"token\";\n\n" + token;
    formString += "\n--abcdefghijklmnop\nContent-Disposition: form-data; name=\"filetype\";\n\n" + filetype;
    formString += "\n--abcdefghijklmnop\nContent-Disposition: form-data; name=\"filename\";\n\n" + filename;
    formString += "\n--abcdefghijklmnop\nContent-Disposition: form-data; name=\"channels\";\n\n" + channel;
    formString += "\n--abcdefghijklmnop\nContent-Disposition: form-data; name=\"title\";\n\n" + title;
    formString += "\n--abcdefghijklmnop\nContent-Disposition: form-data; filename=\"" + upfile + "\"; name=\"file\";\nContent-Type:application/octet-stream;\n\n";
    var options = {
        method: 'post',
        url: 'https://slack.com/api/files.upload',
        headers: {"Content-Type": "multipart/form-data; boundary=abcdefghijklmnop"},
        body: Buffer.concat([
            Buffer.from(formString, "utf8"),
            new Buffer(content, 'binary'),
            Buffer.from("\n--abcdefghijklmnop\n", "utf8"),
        ]),
    };
    request(options, function(error, response, body) {
        console.log(body);
    });
});

示例脚本2:

这比示例1更简单。您可以使用fs.createReadStream()作为文件上传到Slack。

var fs = require('fs');
var request = require('request');
request.post({
    url: 'https://slack.com/api/files.upload',
    formData: {
        file: fs.createReadStream('sample.zip'),
        token: '### access token ###',
        filetype: 'zip',
        filename: 'samplefilename',
        channels: 'sample',
        title: 'sampletitle',
    },
}, function(error, response, body) {
    console.log(body);
});

结果:

样本1和样本2都可以将zip文件上传到Slack,如下所示。对于这两者,即使未定义filetype,上传的文件也会自动用作zip文件。

enter image description here

如果我误解了你的问题,我很抱歉。