Опубликовать 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.

Ответ 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 не даст вам соответствующую строку запроса. Говорится:

  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"

Ответ 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