Mam kilka parametrów, które chcę POST zakodować na moim serwerze:
{
'userName': '[email protected]',
'password': 'Password!',
'grant_type': 'password'
}
Wysyłam moje żądanie (obecnie bez parametrów) w ten sposób
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
});
Jak mogę dołączyć parametry zakodowane w formularzu do żądania?
javascript
http-post
react-native
fetch-api
texas697
źródło
źródło
Odpowiedzi:
Do przesyłania żądań POST zakodowanych w formularzu polecam użycie obiektu FormData .
Przykładowy kod:
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);
źródło
application/x-www-form-urlencoded
, a niemultipart/form-data
.Musisz samodzielnie złożyć ładunek x-www-form-urlencoded, na przykład:
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 })
Zauważ, że jeśli używasz
fetch
w (wystarczająco nowoczesnej) przeglądarce, zamiast React Native, możesz zamiast tego utworzyćURLSearchParams
obiekt i użyć go jako ciała, ponieważ Fetch Standard stwierdza, że jeślibody
jestURLSearchParams
obiektem, powinien być serializowany jakoapplication/x-www-form-urlencoded
. Jednak nie możesz tego zrobić w React Native, ponieważ React Native nie implementujeURLSearchParams
.źródło
const formBody = Object.keys(details).map(key => encodeURIComponent(key) + '=' + encodeURIComponent(details[key])).join('&');
const formBody = Object.entries(details).map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value)).join('&')
Jeszcze prostsze:
body: new URLSearchParams({ 'userName': '[email protected]', 'password': 'Password!', 'grant_type': 'password' }),
Dokumenty: https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch
źródło
Posługiwać się
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');
źródło
URLSearchParams
nie istnieje w React Native. (Zobacz github.com/facebook/react-native/issues/9596. )toString()
dane przed przekazaniem żądaniabody
.URLSearchParams
, nadal mam problemy. Nie sądzę, że jest zaimplementowany zgodnie ze specyfikacją i nie jest to tylko kropla w rozwiązaniu. Proszę rozważyć przeczytanie URLSearchParams „Error: not Implemented”, jeśli próbujesz wpaśćURLSearchParams
i nadal masz problemy.Właśnie to zrobiłem i UrlSearchParams załatwił sprawę Oto mój kod, jeśli komuś pomoże
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; };
źródło
*/ 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)) })
Po użyciu npm i querystring - zapisz, że działa dobrze.
źródło
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 })
jest to dla mnie bardzo pomocne i działa bez żadnego błędu
odniesienie: https://gist.github.com/milon87/f391e54e64e32e1626235d4dc4d16dc8
źródło
Po prostu użyj
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))
źródło
Nie ma potrzeby używania jQuery
querystring
ani ręcznego składania ładunku.URLSearchParams
jest do zrobienia, a oto jedna z najbardziej zwięzłych odpowiedzi z przykładem pełnego zapytania: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 });
Tak, zamiast tego możesz użyć Axios lub czego tylko chcesz
fetch
.PS
URLSearchParams
nie jest obsługiwany w IE.źródło
Po prostu ustaw ciało w następujący sposób
var reqBody = "username="+username+"&password="+password+"&grant_type=password";
następnie
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)})
źródło
W oryginalnym przykładzie masz plik
transformRequest
funkcję, która konwertuje obiekt na dane zakodowane w formacie Form.W poprawionym przykładzie zastąpiłeś to
JSON.stringify
który konwertuje obiekt na JSON.W obu przypadkach masz
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
więc roszczenie być wysyłania danych zakodowanej formie w obu przypadkach.Zamiast tego użyj funkcji kodowania formularza
JSON.stringify
.Ponowna aktualizacja:
W pierwszym
fetch
przykładzie ustawiaszbody
wartość JSON.Teraz utworzyłeś wersję Form Encoded, ale zamiast ustawiania
body
tej wartości, utworzyłeś nowy obiekt i ustawiłeś dane Form Encoded jako właściwość tego obiektu.Nie twórz dodatkowego obiektu. Po prostu przypisz swoją wartość do
body
.źródło
Jeśli używasz JQuery, to też działa.
fetch(url, { method: 'POST', body: $.param(data), headers:{ 'Content-Type': 'application/x-www-form-urlencoded' } })
źródło
Zgodnie ze specyfikacją użycie
encodeURIComponent
nie daje zgodnego ciągu zapytania. W Stanach:Problem w tym, że
encodeURIComponent
zakoduje przestrzenie, które mają być%20
, a nie+
.Treść formularza powinna być zakodowana przy użyciu różnych
encodeURIComponent
metod przedstawionych w innych odpowiedziach.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"
źródło
Możesz użyć aplikacji React-Native-Easy, która ułatwia wysyłanie żądań http i formułowanie żądań przechwycenia.
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); } });
źródło