如何使用内容类型 ='application/x-www-form-urlencoded' 在 node.js 中发布数据
Posted
技术标签:
【中文标题】如何使用内容类型 =\'application/x-www-form-urlencoded\' 在 node.js 中发布数据【英文标题】:how to post data in node.js with content type ='application/x-www-form-urlencoded'如何使用内容类型 ='application/x-www-form-urlencoded' 在 node.js 中发布数据 【发布时间】:2016-05-30 03:14:19 【问题描述】:我在使用 Content-type: 'application/x-www-form-urlencoded'
在 node.js 中发布数据时遇到问题
var loginArgs =
data: 'username="xyzzzzz"&"password="abc12345#"',
//data:
// 'username': "xyzzzzz",
// 'password': "abc12345#",
//,
headers:
'User-Agent': 'MYAPI',
'Accept': 'application/json',
'Content-Type':'application/x-www-form-urlencoded'
;
并且发布请求是:
client.post("http:/url/rest/login", loginArgs, function(data, response)
console.log(loginArgs);
if (response.statusCode == 200)
console.log('succesfully logged in, session:', data.msg);
它总是返回用户名/密码不正确。
在其余的 api 中说请求正文应该是:
username='provide user name in url encoded
format'&password= "provide password in url encoded format'
【问题讨论】:
How to make an HTTP POST request in node.js?的可能重复 【参考方案1】:request
支持application/x-www-form-urlencoded
和multipart/form-data
表单上传。对于multipart/related
,请参阅多部分 API。
application/x-www-form-urlencoded(URL 编码表单)
URL 编码的表单很简单:
const request = require('request');
request.post('http:/url/rest/login',
form:
username: 'xyzzzzz',
password: 'abc12345#'
)
// or
request.post('http:/url/rest/login').form(
username: 'xyzzzzz',
password: 'abc12345#'
)
// or
request.post(
url: 'http:/url/rest/login',
form:
username: 'xyzzzzz',
password: 'abc12345#'
, function (err, httpResponse, body) /* ... */ )
见:https://github.com/request/request#forms
或者,使用request-promise
const rp = require('request-promise');
rp.post('http:/url/rest/login',
form:
username: 'xyzzzzz',
password: 'abc12345#'
).then(...);
见:https://github.com/request/request-promise#api-in-detail
【讨论】:
此评论不再适用。request
模块被标记为已弃用。 github.com/request/request/issues/3142【参考方案2】:
application/x-www-form-urlencoded 要求您对键和值进行 URL 编码 (MSDN Documentation)。 举例说明:
data:`$encodeURI('username')=$encodeURI('xyzzzzz')&$encodeURI('password')=$encodeURI('abc12345')`
请求库已被弃用,正如@Bram 所评论的那样。
我将编写的示例将使用 NodeJS 附带的标准 HTTPS 库。 你可以这样写(在打字稿中):
import * as https from 'https';
// import * as http from 'http'; // For HTTP instead of HTTPS
export class ApiExample
// tslint:disable-next-line: no-empty
constructor()
public async postLogin(username: string, password: string): Promise<any>
// application/x-www-form-urlencoded requires the syntax "UrlEncodedKey=UrlEncodedValue&UrlEncodedKey2=UrlEncodedValue2"
const xFormBody = `$encodeURI('username')=$encodeURI(username)&$encodeURI('password')=$encodeURI(password)`;
return this.performRequest(xFormBody)
private performRequest(requestBody: string)
return new Promise((resolve, reject) =>
const options: https.RequestOptions =
hostname: 'example.url.com',
port: 443,
path: '/login',
method: 'POST',
headers:
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(requestBody)
;
// const req = http.request(options, function (res) // For HTTP
const req = https.request(options, function (res)
// This may need to be modified based on your server's response.
res.setEncoding('utf8');
let responseBody = '';
// Build JSON string from response chunks.
res.on('data', (chunk) => responseBody = responseBody + chunk);
res.on('end', function ()
const parsedBody = JSON.parse(responseBody + '');
// Resolve or reject based on status code.
res.statusCode !== 200 ? reject(parsedBody) : resolve(parsedBody);
);
);
// Make sure to write the request body.
req.write(requestBody);
req.end();
req.on('error', function (e) reject(e); );
);
export default ApiExample;
【讨论】:
【参考方案3】:如果你使用的是 axios 包,这里是解决方案。
如果标题为Content-type: 'application/x-www-form-urlencoded'
那么你将调用 post API 为
const response: any = await axios.post(URL, bodyData,
headers:
'Content-Type': 'application/x-www-form-urlencoded'
);
URL 是您的 API url,例如 http//YOUR_HOST/XYZ...,以及
bodyData 是您要在 post API 中发送的数据,
现在你将如何通过它?
假设你有数据作为对象,所以你必须将它编码为 url,让我告诉你
let data =
username: name,
password: password
那么你的 bodyData 会是这样的
let bodyData = `username=$name&password=$password`
如果标题是,这是您可以在正文中传递数据的方式
Content-type: 'application/x-www-form-urlencoded'
如果您有大量无法手动编码的数据,则可以使用qs 模块
运行命令npm i qs
并在您的文件中
const qs = require('qs');
...
let data =
username: name,
password: password,
manyMoreKeys: manyMoreValues
let bodyData = qs.stringify(data);
【讨论】:
【参考方案4】:使用节点的 URLSearchParams 类将 js 对象编码为“url 编码”形式,并将字符串作为请求正文传递。 Documentation
【讨论】:
一个代码示例可能会更清楚地解释这一点:``` const a = new URLSearchParams(); a.append('测试', '值'); a.append('test2', 'value2');控制台.log(a.toString()); // 将记录 'test=value&test2=value2' ```【参考方案5】:如果您使用的是got package
const got = require('got');
const qs = require('qs');
const body = qs.stringify(
a: 'd',
b: 'b',
c: 'c',
);
在异步函数中
const response = await got.post(url, body );
如果 Content-Type 标头不存在,它将被设置为 application/x-www-form-urlencoded
【讨论】:
【参考方案6】:我认为got package 具有有效的内置功能:
const got = require('got');
const response = await got.post(url, form: a: 'd', b: 'b', c: 'c');
【讨论】:
以上是关于如何使用内容类型 ='application/x-www-form-urlencoded' 在 node.js 中发布数据的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Spring Boot Web 客户端为内容类型 application/x-www-form-urlencoded 的表单数据发布请求
使用 Firefox 的 HTTP 内容类型“application/x-itunes-itlp”
使用“application/x-www-form-urlencoded”内容类型请求标头时,未正确发送 HttpClient 后正文参数
使用内容类型为:application/x-www-form-urlencoded 的 POST Fetch 调用时,从服务器返回本机 422 Unprocessable Entity 错误
@RequestBody MultiValueMap 不支持内容类型 'application/x-www-form-urlencoded;charset=UTF-8'