Javascript 如何使用Fetch发布x-www-form-urlencoded请求?
我有一些参数要发布到我的服务器上:Javascript 如何使用Fetch发布x-www-form-urlencoded请求?,javascript,http-post,fetch-api,Javascript,Http Post,Fetch Api,我有一些参数要发布到我的服务器上: { 'userName': 'test@gmail.com', 'password': 'Password!', 'grant_type': 'password' } 我发送的请求(目前没有参数)如下 var obj = { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', }
{
'userName': 'test@gmail.com',
'password': 'Password!',
'grant_type': 'password'
}
我发送的请求(目前没有参数)如下
var obj = {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
},
};
fetch('https://example.com/login', obj)
.then(function(res) {
// Do stuff with result
});
如何在请求中包含表单编码参数?在原始示例中,您有一个
transformRequest
函数,用于将对象转换为表单编码数据
在修订后的示例中,您将其替换为将对象转换为JSON的JSON.stringify
在这两种情况下,您都有“Content-Type”:“application/x-www-form-urlencoded;charset=UTF-8'
所以您声称在这两种情况下都在发送表单编码的数据
使用表单编码函数而不是JSON.stringify
重新更新: 在第一个
fetch
示例中,将body
设置为JSON值
现在您已经创建了一个表单编码版本,但是没有将body
设置为该值,而是创建了一个新对象,并将表单编码数据设置为该对象的属性
不要创建那个额外的对象。只需将您的值分配给
body
对于上传表单编码的POST请求,我建议使用对象
示例代码:
var params = {
userName: 'test@gmail.com',
password: 'Password!',
grant_type: 'password'
};
var formData = new FormData();
for (var k in params) {
formData.append(k, params[k]);
}
var request = {
method: 'POST',
headers: headers,
body: formData
};
fetch(url, request);
您必须自己组装x-www-form-urlencoded负载,如下所示:
var details = {
'userName': 'test@gmail.com',
'password': 'Password!',
'grant_type': 'password'
};
var formBody = [];
for (var property in details) {
var encodedKey = encodeURIComponent(property);
var encodedValue = encodeURIComponent(details[property]);
formBody.push(encodedKey + "=" + encodedValue);
}
formBody = formBody.join("&");
fetch('https://example.com/login', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
},
body: formBody
})
请注意,如果在(足够现代的)浏览器中使用
fetch
,而不是React Native,则可以创建一个对象并将其用作主体,因为如果body
是URLSearchParams
对象,则应将其序列化为application/x-www-form-urlcoded
。但是,您不能在React-Native中执行此操作,因为React-Native。使用URLSearchParams
只用
import qs from "qs";
let data = {
'profileId': this.props.screenProps[0],
'accountId': this.props.screenProps[1],
'accessToken': this.props.screenProps[2],
'itemId': this.itemId
};
return axios.post(METHOD_WALL_GET, qs.stringify(data))
如果您使用的是JQuery,那么它也可以工作
fetch(url, {
method: 'POST',
body: $.param(data),
headers:{
'Content-Type': 'application/x-www-form-urlencoded'
}
})
根据,使用encodeURIComponent
不会给您提供一致的查询字符串。它说:
+
,然后按照[RFC1738]第2.2节:非字母数字字符替换为%HH
,一个百分号和两个十六进制数字,表示字符的ASCII码。换行符表示为“CR LF”对(即,%0D%0A
)=
分隔,名称/值对之间用&
分隔encodeURIComponent
将空格编码为%20
,而不是+
表单正文应使用其他答案中所示的encodeURIComponent
方法的变体进行编码
const formUrlEncode = str => {
return str.replace(/[^\d\w]/g, char => {
return char === " "
? "+"
: encodeURIComponent(char);
})
}
const data = {foo: "bar߃©˙∑ baz", boom: "pow"};
const dataPairs = Object.keys(data).map( key => {
const val = data[key];
return (formUrlEncode(key) + "=" + formUrlEncode(val));
}).join("&");
// dataPairs is "foo=bar%C3%9F%C6%92%C2%A9%CB%99%E2%88%91++baz&boom=pow"
就这么做了,UrlSearchParams就成功了 这是我的代码,如果它对某人有帮助的话
import 'url-search-params-polyfill';
const userLogsInOptions = (username, password) => {
// const formData = new FormData();
const formData = new URLSearchParams();
formData.append('grant_type', 'password');
formData.append('client_id', 'entrance-app');
formData.append('username', username);
formData.append('password', password);
return (
{
method: 'POST',
headers: {
// "Content-Type": "application/json; charset=utf-8",
"Content-Type": "application/x-www-form-urlencoded",
},
body: formData.toString(),
json: true,
}
);
};
const getUserUnlockToken = async (username, password) => {
const userLoginUri = `${scheme}://${host}/auth/realms/${realm}/protocol/openid-connect/token`;
const response = await fetch(
userLoginUri,
userLogsInOptions(username, password),
);
const responseJson = await response.json();
console.log('acces_token ', responseJson.access_token);
if (responseJson.error) {
console.error('error ', responseJson.error);
}
console.log('json ', responseJson);
return responseJson.access_token;
};
更简单的是:
fetch('https://example.com/login', {
方法:“POST”,
正文:新URLSearchParams({
“用户名”:”test@gmail.com',
“密码”:“密码!”,
“授权类型”:“密码”
})
});
文件:
使用npm i querystring后——保存工作正常
var details = {
'userName': 'test@gmail.com',
'password': 'Password!',
'grant_type': 'password'
};
var formBody = [];
for (var property in details) {
var encodedKey = encodeURIComponent(property);
var encodedValue = encodeURIComponent(details[property]);
formBody.push(encodedKey + "=" + encodedValue);
}
formBody = formBody.join("&");
fetch('http://identity.azurewebsites.net' + '/token', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded'
},
body: formBody
})
这对我很有帮助,而且没有任何错误
参考:您可以使用更容易发送http请求和制定拦截请求的方法
import { XHttp } from 'react-native-easy-app';
* Synchronous request
const params = {name:'rufeng',age:20}
const response = await XHttp().url(url).param(params).formEncoded().execute('GET');
const {success, json, message, status} = response;
* Asynchronous requests
XHttp().url(url).param(params).formEncoded().get((success, json, message, status)=>{
if (success){
this.setState({content: JSON.stringify(json)});
} else {
showToast(msg);
}
});
无需使用jQuery、
querystring
或手动组装负载URLSearchParams
是一种方法,下面是一个最简洁的答案,包含完整的请求示例:
fetch('https://example.com/login', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
'param': 'Some value',
'another_param': 'Another value'
})
})
.then(res => {
// Do stuff with the result
});
是的,您可以使用Axios或任何您想要的工具,而不是fetch
注意:IE中不支持URLSearchParams。只需将主体设置为以下内容
var reqBody = "username="+username+"&password="+password+"&grant_type=password";
然后
这不是application/x-www-form-urlencoded,而是multipart/form-dataI concure,此请求的内容类型不是“application/x-www-form-urlencoded”,而是“multipart/form-data”。@Mzn-例如,如果您使用的是像谷歌这样的服务,服务器将只接受
application/x-www-form-urlencoded
,不是multipart/form data
。这怎么可能是公认的答案?关于实际问题,这显然是错误的……在提交FormData对象时,您必须在服务器上进行额外的处理。基本上是像文件上传一样处理常规表单。对于常规表单,FormData对象的优势是什么?ES6方式:constFormBody=Object.keys(details).map(key=>encodeURIComponent(key)+'='+encodeURIComponent(details[key])。join('&')
URLSearchParams的polyfill可能适用于React本机或旧版浏览器。另一种类似的方法:在React-Native中不存在。(请参阅)它现在是React-Native的一部分。一定要调用const formBody=Object.entries(details).map([key,value])=>encodeURIComponent(key)+'='+encodeURIComponent(value)).join('&')
URLSearchParams
toString()在传递请求之前的数据<代码>正文< /代码>。即使RN说他们执行了代码> URLSearchParams < /代码>,我仍然有问题。我不认为它是按照规范来实现的,它不仅仅是解决方案中的一个问题。如果您试图进入代码< URLSearchParams >,请考虑阅读。
fetch('https://example.com/login', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
'param': 'Some value',
'another_param': 'Another value'
})
})
.then(res => {
// Do stuff with the result
});
var reqBody = "username="+username+"&password="+password+"&grant_type=password";
fetch('url', {
method: 'POST',
headers: {
//'Authorization': 'Bearer token',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
},
body: reqBody
}).then((response) => response.json())
.then((responseData) => {
console.log(JSON.stringify(responseData));
}).catch(err=>{console.log(err)})