web-dev-qa-db-ja.com

React Nativeからx-www-form-urlencodedリクエストを投稿します

サーバーに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
  }); 

リクエストにフォームエンコードされたパラメーターを含めるにはどうすればよいですか?

56
texas697

次のように、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
})

if(十分に近代的な)ブラウザでReact Nativeの代わりにfetchを使用していたことに注意してください。 URLSearchParams オブジェクトであり、それを本文として使用します。これは フェッチ標準の状態bodyURLSearchParamsオブジェクトである場合、application/x-www-form-urlencodedとしてシリアル化する必要があるためです。ただし、React Native URLSearchParamsを実装しない であるため、React Nativeでこれを行うことはできません。

166

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

これを実行し、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;
};
5
P-A

さらに簡単:

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

ただ使う

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

JQueryを使用している場合、これも機能します。

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

元の例では、オブジェクトをフォームエンコードデータに変換するtransformRequest関数があります。

改訂された例では、オブジェクトをJSONに変換するJSON.stringifyに置き換えました。

どちらの場合も'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'があるので、どちらの場合もclaimingでフォームエンコードデータを送信します。

JSON.stringifyの代わりにフォームエンコーディング関数を使用します。


再更新:

最初のfetchの例では、bodyをJSON値に設定します。

これで、フォームエンコードバージョンを作成しましたが、bodyをその値に設定する代わりに、新しいオブジェクトを作成し、フォームエンコードデータをそのオブジェクトのプロパティとして設定しました。

その余分なオブジェクトを作成しないでください。値を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))
    })

npm i querystring --saveを使用した後、正常に動作します。

0
Akshita Agarwal

仕様 によると、encodeURIComponentを使用しても、適合するクエリ文字列は得られません。状態:

  1. コントロールの名前と値はエスケープされます。 スペース文字は+に置き換えられ、その後、予約文字は[RFC1738]セクション2.2で説明されているようにエスケープされます:英数字以外の文字は%HHに置き換えられます。パーセント記号と、文字のASCIIコードを表す2つの16進数。改行は「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"
0
papiro