web-dev-qa-db-fra.com

Poster une requête x-www-form-urlencoded de React Native

J'ai certains paramètres que je veux POST coder sous forme sur mon serveur

{
    'userName': '[email protected]',
    'password': 'Password!',
    'grant_type': 'password'
}

J'envoie ma demande (actuellement sans paramètre) comme ceci

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

Comment puis-je inclure les paramètres codés par formulaire dans la demande?

52
texas697

Vous devez assembler vous-même la charge utile x-www-form-urlencoded, comme ceci:

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

Notez que si vous utilisiez fetch dans un navigateur (suffisamment moderne), au lieu de React Native, vous pouvez créer un objet URLSearchParams et l'utiliser comme corps, car Fetch Standard indique que si la body est un objet URLSearchParams, il doit alors être sérialisé en tant que application/x-www-form-urlencoded. Cependant, vous ne pouvez pas le faire dans React Native car React Native n'implémente pas URLSearchParams .

152

Utilisez 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');
16
Nicu Criste

Je viens de faire cela et UrlSearchParams a fait le tour Voici mon code s'il aide quelqu'un

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
P-A

Juste utiliser 

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))
2
mojTaba Shayegh

Encore plus simple:

body: new URLSearchParams({
      'userName': '[email protected]',
      'password': 'Password!',
      'grant_type': 'password'
    }),
1
alex_1948511

Si vous utilisez JQuery, cela fonctionne aussi ..

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

Dans l'exemple d'origine, vous avez une fonction transformRequest qui convertit un objet en données codées par formulaire.

Dans l'exemple révisé, vous avez remplacé cela par JSON.stringify qui convertit un objet en JSON.

Dans les deux cas, vous avez 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' et vous êtes donc {réclamez} _ à envoyer des données de formulaire codé dans les deux cas.

Utilisez votre fonction de codage de formulaire au lieu de JSON.stringify.


Re mise à jour:

Dans votre premier exemple fetch, vous définissez la variable body comme valeur JSON.

Vous avez maintenant créé une version de formulaire codé, mais au lieu de définir la valeur body sur cette valeur, vous avez créé un nouvel objet et défini les données de formulaire codé comme une propriété de cet objet.

Ne créez pas cet objet supplémentaire. Attribuez simplement votre valeur à body

1
Quentin
*/ 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))
    })

Après avoir utilisé npm i querystring --save cela fonctionne bien.

0
Akshita Agarwal

Selon la spécification , utiliser encodeURIComponent ne vous donnera pas une chaîne de requête conforme. Il est dit:

  1. Les noms de contrôle et les valeurs sont échappés. Les caractères Space sont remplacés par +, puis les caractères réservés sont échappés comme décrit dans la section [RFC1738], section 2.2: Les caractères non alphanumériques sont remplacés par %HH, un signe de pourcentage et deux chiffres hexadécimaux représentant le ASCII code du personnage. Les sauts de ligne sont représentés par des paires "CR LF" (c.-à-d. %0D%0A).
  2. Les noms/valeurs de contrôle sont répertoriés dans l'ordre dans lequel ils apparaissent dans le document. Le nom est séparé de la valeur par = et les paires nom/valeur sont séparées les unes des autres par &.

Le problème est que encodeURIComponent code les espaces comme étant %20 et non +.

Le corps du formulaire doit être codé en utilisant une variante des méthodes encodeURIComponent présentées dans les autres réponses.

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
papiro