使用本机节点模块发送表单数据

Sending Form Data with the native node module

对于我当前的项目,我必须将表单数据从我的 lambda 函数发送到 api 端点。 api 端点本质上需要两个图像(它相互比较)和一个密钥。如前所述,我似乎无法将正确的表单数据发送到 api 端点。我检查了邮递员,它似乎工作正常,但我的功能似乎不起作用。我认为它必须与我发送的表单数据字符串相关。您可以在下面找到该函数的简化版本(我排除了两个图像文件),但不知何故我收到错误消息,告诉我 api 无法读取密钥 属性:

const http = require('http');
const https = require('https');
const httpPromise = (protocol, params, postData) => {
    return new Promise((resolve, reject) => {
        const requestModule = protocol === 'http' ? http : https;
        const req = requestModule.request(params, res => {
            // grab request status
            const statusCode = res.statusCode;
            if(statusCode < 200 || statusCode > 299) {
                throw new Error('Request Failed with Status Code:', statusCode);
            }

            let body = '';
            // continuosly update data with incoming data
            res.setEncoding('utf8');
            res.on('data', data => body += data);

            // once all data was received
            res.on('end', () => resolve(body));
        })

        // write data to a post request
        if(typeof(params.method) === 'string' && params.method === 'POST' && postData) {
            req.write(postData)
        }


        // bind to the error event
        req.on('error', err => reject(err));

        // end the request
        req.end();
    })
}

const controller = async () => {
    const apiKey = "00000000";
    const options = {
        hostname: '***"
        port: 80,
        path: '***'
       method: 'POST',
       headers: {"content-type": "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW"}
    }
    const postData = "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"key\"\r\n\r[=10=]000000\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--"
    let result = await httpPromise('http', options, postData)
    console.log(result);
}

是的,所以它似乎无法识别 postData 字符串中的键。我尝试了各种不同的组合,但似乎无法让它发挥作用。

默认的 http 和 https 库有点冗长和烦人。

建议改用 request 库。阅读更多 here

在这种情况下,要发出请求,您只需将其写为:

var request = require('request');

var formData = {
  // Pass a simple key-value pair
  my_field: 'my_value',
}

request.post({url:'http://service.com/upload', formData: formData}, (err, response, body) => {
   // Handle response here
});

好吧,对于可能也面临同样问题的任何人,我花了一点时间才弄清楚问题是什么。我没有设置 Content-Length header,这反过来意味着节点会自动添加 Transfer-Encoding Header 并将其值设置为块。这破坏了接收 api 并导致了问题。将 Content-Length header 设置为正确的长度并将 Transfer-Encoding Header 设置为空字符串解决了我的问题(但我认为也可以简单地省略 transfer-encoding header 一旦你定义了 Content-Length Header)。