【问题标题】:Node request module not setting Content-Type as application/json节点请求模块未将 Content-Type 设置为 application/json
【发布时间】:2017-09-20 10:17:43
【问题描述】:

我的 NodeJS/Koa.js 应用程序遇到了一个奇怪的问题,我发出的 HTTP 请求返回此错误消息:

{"Message":"The request entity's media type 'application/x-www-form-urlencoded' is not supported for this resource."

现在,当我使用邮递员发出相同的请求时,我得到了正确的结果,因此我推断我的代码中有问题。我似乎无法弄清楚。这是我发出请求和有效负载的代码。

 // Content Type
        if(options.contentType === 'json') {
            headers['Content-Type'] = 'application/json';
        }

        // Content Length
        if(options.contentLength) {
            reqHeaders['Content-Length'] = options.contentLength
        }

        if(headers) {
            for(let key in headers) {
                if(!headers.hasOwnProperty(key)) {
                    continue;
                }

                reqHeaders[key] = headers[key];
            }
        }

        const payload = {
            headers : reqHeaders,
            url     : url,
            method  : requestType,
            timeout : 10000,
            form    : vars,
            followRedirect: true,
            maxRedirects: 10,
            body    : '' || options.body
        };

        return new Promise(function(resolve, reject) {
            request(payload, function(error, response, body) {
                if(response) {
                    if(!error && response.statusCode === 200) {
                        resolve(response, body);
                    } else {
                        if(response.statusCode === 401) {
                            console.log('token expired');
                        }
                        reject(response, body);
                    }
                }
            });
        });

有效载荷:

{
  "headers": {
    "Cookie": "XDEBUG_SESSION=PHPSTORM",
    "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJkZWdvdWxkLWxvZ2luLmRldiIsImFjY291bnQiOiI1OTY3NmFmZmYyOWE1NWI2MTViOWFiMWEiLCJhdXRoTGV2ZWwiOjAsImlhdCI6MTUwNTg5OTQ3MX0.r-XaeTsQTjSkab9SNjrHgnh6lrgNP0uJCaDIV22A6gM",
    "Content-Type": "application/json"
  },
  "url": "http://54.***.***/api/Report/History",
  "method": "POST",
  "timeout": 10000,
  "form": {
    "AccountId": "59676afff29a55b615b9ab1a",
    "StartDate": "2017-09-19T10:11:47.0266607+00:00",
    "EndDate": "2017-09-19T10:11:47.0266607+00:00",
    "VIN": "SALLAK"
  },
  "followRedirect": true,
  "maxRedirects": 10
}

如您所见,我的标头对象中有正确的 Content-Type 标头,该标头位于我传递给请求函数的有效负载中,但它仍然看起来好像是以 x-www-form-encoded 形式发送的。谁能看到这里可能出了什么问题?

谢谢

【问题讨论】:

    标签: json node.js http post request


    【解决方案1】:

    docs 阅读:

    • form - 当传递一个对象或查询字符串时,这会将 body 设置为 value 的查询字符串表示,并添加 Content-type: application/x-www-form-urlencoded 标头。

    • json - 将正文设置为值的 JSON 表示并添加 Content-type: application/json 标头。

    您正在使用form,因此它会覆盖标题。尝试改用json。无论如何它都会覆盖您的标题,但该值将是“应用程序/json”,这应该没问题。

    【讨论】:

    • 完美!谢谢
    【解决方案2】:

    如果可以的话,有几个建议:

    • 您可以使用 Object.assign 设置对象中的标题。
    • 设置json: true 将负责放置正确的内容类型标头。
    • 您不必手动设置内容长度,这是一件棘手的事情。让 request 来处理。
    • 如果您想返回一个承诺,请考虑使用启用了fullResponse 的 request-promise 来检查令牌是否过期。

      if(headers) {
        Object.assign(reqHeaders, headers);
      }
      
      const payload = {
         headers: reqHeaders,
         url: url,
         method: requestType,
         timeout: 10000,
         json: true,
         followRedirect: true,
         maxRedirects: 10,
         body: options.body || {},
         fullResponse: true
      };
      
      return rp(payload).then(function(response) {
        if (response.statusCode === 401) {
          throw Error('Token expired');
        }
        return response.body;
      });
      

    【讨论】:

    • 谢谢!原始类是不久前编写的,因此所有这些内容都将在重新格式化时实现。不过感谢您的建议。很有帮助
    猜你喜欢
    • 1970-01-01
    • 2015-10-20
    • 2016-10-02
    • 2012-05-22
    • 2022-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多