React Native'den bir x-www-form-urlencoded istek gönderin


104

Sunucuma form kodlu POST göndermek istediğim bazı parametrelerim var:

{
    'userName': 'test@gmail.com',
    'password': 'Password!',
    'grant_type': 'password'
}

İsteğimi (şu anda parametreler olmadan) bu şekilde gönderiyorum

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
  }); 

Form kodlu parametreleri isteğe nasıl dahil edebilirim?


2
Lütfen seçtiğiniz cevabı gerçek doğru cevapla güncelleyin.
Albert Renshaw

Yanıtlar:


-49

Form Kodlu POST isteklerini karşıya yüklemek için FormData nesnesini kullanmanızı öneririm .

Örnek kod:

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);

79
Bu uygulama / x-www-form-urlencoded değil, multipart / form-data
Haha TTpro

Kabul ediyorum, bu istek İçerik Türü olarak "application / x-www-form-urlencoded" değil, "multipart / form-data" olacak.
b4stien

2
@Mzn - Örneğin, Google'ın Closure Compiler API'si gibi bir hizmet kullanıyorsanız , sunucu yalnızca kabul eder application/x-www-form-urlencoded, kabul etmez multipart/form-data.
Sphinxxx

12
Bu nasıl kabul edilen cevap olabilir? Asıl soru ile ilgili kesinlikle yanlış ...
Żabojad

1
FormData nesnelerini gönderirken sunucuda fazladan işlem yapmanız gerekir. Temelde normal bir formu bir dosya yüklemesi gibi işleyin. Normal formlar için FormData nesnelerinin avantajı nedir?
MarsAndBack

251

X-www-form-urlencoded yükünü aşağıdaki gibi bir araya getirmelisiniz:

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
})

O Not eğer kullandığınız idi fetchyerine Doğalöğesini tepki arasında bir (yeterince Modern) tarayıcıda, bunun yerine bir yaratabileceği URLSearchParamsberi o organ olarak nesne ve kullanımı Standart Fetch devletler eğer bodybir olduğunu URLSearchParamsnesne daha sonra o kadar dizgeleştirilecek application/x-www-form-urlencoded. Ancak bunu React Native'de yapamazsınız çünkü React Native uygulanmazURLSearchParams .


50
ES6 yöntemi:const formBody = Object.keys(details).map(key => encodeURIComponent(key) + '=' + encodeURIComponent(details[key])).join('&');
Eric Burel

URLSearchParams github.com/WebReflection/url-search-params için bu çoklu doldurma , React Native veya daha eski tarayıcılarda çalışabilir.
bucabay

7
Başka bir benzer yol:const formBody = Object.entries(details).map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value)).join('&')
Flynn Hou

1
Json dizi parametresini dizeye dönüştürür
atulkhatri


47

Kullanım URLSearchParams

https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams

var data = new URLSearchParams();
data.append('userName', 'test@gmail.com');
data.append('password', 'Password');
data.append('grant_type', 'password');

php7 FormData kodlamasını doğru çözümlemediğinden, bu benim istediğim şeyi yapar. Umarım PHP'nin erkekleri ve
kızları

6
-1; URLSearchParamsReact Native'de mevcut değil. (Bkz. Github.com/facebook/react-native/issues/9596. )
Mark Amery

3
Artık React Native'in bir parçası. toString()İsteği iletmeden önce verileri aradığınızdan emin olun body.
phatmann

RN uyguladıklarını söyledikten sonra bile URLSearchParamshala sorunlar yaşıyorum. Spesifikasyona uygun olarak uygulandığını sanmıyorum ve bu sadece bir çözümde düşüş değil. Bırakmaya çalışırsanız URLSearchParamsve hala sorun yaşıyorsanız, lütfen URLSearchParams 'Hata: uygulanmadı' bölümünü okuyun .
zero298

14

Bunu yaptım ve UrlSearchParams hile yaptı Birisine yardımcı oluyorsa işte kodum

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;
};

5
*/ 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 i querystring'i kullandıktan sonra - sorunsuz çalışıyor.


5
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
})

benim için çok faydalı ve hatasız çalışıyor

referans: https://gist.github.com/milon87/f391e54e64e32e1626235d4dc4d16dc8


3

Sadece kullan

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))

1
Bu doğru cevap olarak işaretlenmelidir. Kullanımı çok kolay ve yapılması gereken tuhaf şeyler yok.
Augusto Gonzalez

1

Orijinal örnekte bir transformRequest , bir nesneyi Form Kodlanmış verilere dönüştüren bir işleve .

Revize edilmiş örnekte JSON.stringify, bir nesneyi JSON'a dönüştürenle değiştirdiniz .

Her iki durumda da var 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'sen bu yüzden da Form Kodlanmış verileri göndermeyi iddia .

Bunun yerine Form Kodlama işlevinizi kullanın JSON.stringify .


Yeniden Güncelleme:

İlk fetchörneğinizde,body JSON değerini .

Artık bir Form Kodlanmış sürüm oluşturdunuz, ancak bunu ayarlamak yerine body bunu bu değer olarak yeni bir nesne oluşturdunuz ve Form Kodlanmış verilerini bu nesnenin bir özelliği olarak ayarladınız.

Bu ekstra nesneyi yaratmayın. Sadece değerinizi atayın body.


Merhaba @Quentin. Gelecekteki okuyucular için daha faydalı bir referans haline getirmek için soruyu radikal bir şekilde inceledim; bunu yaparken, soran kişinin orijinal kodunun ayrıntılarına ve hatalarına atıfta bulunan cevabınızı tamamen geçersiz kıldım. Sanırım, isterseniz düzenlememi geri alma hakkınız var - teoride, cevabı geçersiz kılan düzenlemeler yapmak istemiyoruz, ki ben de bunu yaptım - ama istersen, sanırım Bunun yerine bu yanıtı silmeniz daha iyi olur; IMO, Angular kodu veya önceki başarısız girişim olmadan çok daha güzel.
Mark Amery

1

JQuery kullanıyorsanız, bu da çalışır ..

fetch(url, {
      method: 'POST', 
      body: $.param(data),
      headers:{
        'Content-Type': 'application/x-www-form-urlencoded'
      }
})

1

JQuery kullanmaya querystringveya yükü elle birleştirmeye gerek yok . URLSearchParamsgitmek için bir yoldur ve işte tam istek örneğiyle birlikte en kısa cevaplardan biri:

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
  });

Evet, Axios'u veya bunun yerine istediğinizi kullanabilirsiniz fetch .

PS URLSearchParams, IE'de desteklenmez.


0

Spesifikasyona göre , kullanmak encodeURIComponentsize uygun bir sorgu dizesi sağlamaz. Belirtir:

  1. Kontrol adları ve değerleri atlanır. Boşluk karakterleri ile değiştirilir+ ve ardından ayrılmış karakterler, [RFC1738], bölüm 2.2'de açıklandığı gibi öncelenir: Alfasayısal olmayan karakterler, karakterin %HHASCII kodunu temsil eden bir yüzde işareti ve iki onaltılık rakam ile değiştirilir . Satır kesmeleri "CR LF" çiftleri olarak temsil edilir (ör.%0D%0A ) .
  2. Kontrol adları / değerleri, belgede göründükleri sırayla listelenir. Ad, değerden ile ayrılır =ve ad / değer çiftleri birbirinden ile ayrılır &.

Sorun, encodeURIComponentboşlukları kodluyor %20, değil+ .

Form-gövde encodeURIComponent, diğer cevaplarda gösterilen yöntemlerin bir çeşidi kullanılarak kodlanmalıdır .

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"

0

Http isteği göndermesi ve müdahale talebini formüle etmesi daha kolay olan react-native-easy-app'ı kullanabilirsiniz .

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);
    }
});
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.