Опубликовать запрос x-www-form-urlencoded от React Native

у меня есть некоторые параметры, которые я хочу опубликовать в кодировке формы на моем сервере:

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

Как я могу включить параметры, закодированные в форме, в запрос?

7 ответов


для загрузки запросов POST, закодированных в форме, я рекомендую использовать виде FormData "объект".

пример кода:

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 вы можете вместо этого создать URLSearchParams объект и использовать его как тело, так как Fetch стандартные состояния, что если body - это URLSearchParams объект тогда он должен быть сериализован как application/x-www-form-urlencoded. Однако вы не можете сделать это в React Native потому что реагировать родной не реализует URLSearchParams.


использовать 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');

в исходном примере у вас есть transformRequest функция, которая преобразует объект в форму закодированных данных.

в пересмотренном примере вы заменили это на JSON.stringify, который преобразует объект в JSON.

в обоих случаях у вас есть 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' Так вы утверждено для отправки данных в кодировке формы в обоих случаях.

используйте функцию кодирования формы вместо JSON.stringify.


Re обновление:

в свой первый fetch примере body быть значением JSON.

теперь вы создали версию с кодировкой формы, но вместо установки body чтобы быть этим значением, вы создали новый объект и установили данные, закодированные в форме, как свойство этого объекта.

Не создавайте этот дополнительный объект. Просто назначьте значение body.


Просто Использовать

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

по данным спец, используя encodeURIComponent не даст вам соответствующую строку запроса. В нем говорится:

  1. имена и значения элементов управления экранируются. символы пробелов заменяются на +, а затем зарезервированные символы экранируются, как описано в [RFC1738], раздел 2.2: не буквенно-цифровые символы заменяются %HH, знак процента и две шестнадцатеричные цифры, представляющие код ASCII символа. Разрывы линий представлено как пары "CR LF" (т. е. %0D%0A).
  2. имена/значения элементов управления перечислены в порядке их отображения в документе. Имя отделяется от значения = и пары имя/значение отделяются друг от друга &.

проблема 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"

Если вы используете jQuery, это тоже работает..

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