Опубликовать x-www-form-urlencoded запрос от React Native
У меня есть некоторые параметры, которые я хочу отправить POST на мой сервер:
{
'userName': '[email protected]',
'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
});
Как включить параметры запроса в форму?
Ответы
Ответ 1
Для загрузки POST-запросов, закодированных в форме, я рекомендую использовать объект FormData.
Пример кода:
var params = {
userName: '[email protected]',
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);
Ответ 2
Вы должны самостоятельно собрать полезную нагрузку x-www-form-urlencoded, например так:
var details = {
'userName': '[email protected]',
'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, вы могли бы вместо этого создать объект URLSearchParams
и использовать его в качестве тела, поскольку стандарт Fetch заявляет, что если body
является объектом URLSearchParams
то оно должно быть сериализованным как application/x-www-form-urlencoded
. Однако вы не можете сделать это в React Native, потому что React Native не реализует URLSearchParams
.
Ответ 3
Использовать URLSearchParams
https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams
var data = new URLSearchParams();
data.append('userName', '[email protected]');
data.append('password', 'Password');
data.append('grant_type', 'password');
Ответ 4
Еще проще:
body: new URLSearchParams({
'userName': '[email protected]',
'password': 'Password!',
'grant_type': 'password'
}),
Ответ 5
Просто сделал это, и 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;
};
Ответ 6
Просто используйте
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))
Ответ 7
В исходном примере у вас есть функция transformRequest
, которая преобразует объект в Form Encoded data.
В пересмотренном примере вы заменили его на JSON.stringify
, который преобразует объект в JSON.
В обоих случаях у вас есть 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
, поэтому вы утверждаете, что отправляете данные с кодировкой формы в обоих случаях.
Используйте функцию Form Encoding вместо JSON.stringify
.
Re update:
В вашем первом примере fetch
вы устанавливаете значение body
как значение JSON.
Теперь вы создали версию с кодировкой формы, но вместо того, чтобы установить это значение body
, вы создали новый объект и задали данные с кодировкой формы как свойство этого объекта.
Не создавайте этот дополнительный объект. Просто присвойте значение body
.
Ответ 8
Если вы используете JQuery, это тоже работает..
fetch(url, {
method: 'POST',
body: $.param(data),
headers:{
'Content-Type': 'application/x-www-form-urlencoded'
}
})
Ответ 9
Согласно спецификации, использование 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"
Ответ 10
*/ import this statement */
import qs from 'querystring'
fetch("*your url*", {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'},
body: qs.stringify({
username: "akshita",
password: "123456",
})
}).then((response) => response.json())
.then((responseData) => {
alert(JSON.stringify(responseData))
})
После использования npm я querystring --save все работает нормально.
Ответ 11
Вы можете добавить функцию к объекту, чтобы упростить сериализацию JSON.
Object.prototype.serialize = function () {
if (!this) return;
var s = []
for (var key in this) {
if (this.hasOwnProperty(key)) {
s.push(encodeURIComponent(key) + '=' + encodeURIComponent(this[key]))
}
}
return s.join('&')
}
Чтобы использовать это, вам просто нужно просто написать
obj.serialize()
Например.
var data = {
a: 1,
b: 2,
c: true
}
fetch('/api_url', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded'
},
body: data.serialize() // see the usage here
})
Ответ 12
var details = {
'userName': '[email protected]',
'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
})
это очень полезно для меня и работает без ошибок
ссылка: https://gist.github.com/milon87/f391e54e64e32e1626235d4dc4d16dc8