2016-02-10 11 views
35

に反応からポストx-www-form-urlencodedで要求:私は自分のサーバーにフォーム・エンコードを投稿したいいくつかのパラメータを持つネイティブ

{ 
    '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オブジェクトの使用をお勧めします。

コード例:あなたはこのように、一緒にx-www-form-urlencodedでペイロード自分自身を配置する必要があり

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

これはapplication/x-www-form-urlencodedではありませんが、multipart/form-data –

+0

私はContent-Typeではなく "multipart/form"として "application/x-www-form-urlencoded" -データ"。 – b4stien

+0

実際に送信された資格情報を検索しているサーバーには、どのような違いがありますか? OAuthエンドポイントは、1つのコンテンツタイプを受け入れ、他のコンテンツタイプを拒否するように設計されていますか? – Mzn

1

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

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

どちらの場合も、'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'がありますので、と書いてと書いて、どちらの場合でもエンコードされたデータを送信してください。

JSON.stringifyの代わりにフォームエンコード関数を使用してください。


再更新:

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

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

余分なオブジェクトを作成しないでください。値をbodyに割り当ててください。

+0

こんにちは@クエンティン。私は、将来の読者のためのより有用な参照にしようとするために、質問を根本的にスリム化しました。そうすることで、私は質問者の元のコードの詳細とバグを完全に無効にしました。私はあなたが望むなら私の編集を元に戻す権利を持っていると思います - 理論的には私たちは私がやったことである無回答の編集をするつもりはありませんが、もしあなたが喜んでいると思うなら代わりにこの答えを削除するほうがよいでしょう。 IMOではAngularコードや以前失敗した試みがなければ、問題ははるかに良くなります。 –

91

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の代わりに(十分に現代的な)ブラウザでは、代わりにオブジェクトを作成し、それを本体として使用することができます。Fetch Standard statesの場合、bodyURLSearchParamsオブジェクトの場合は、application/x-www-form-urlencodedとしてシリアル化する必要があります。ただし、React Native does not implement URLSearchParamsが原因でReact Nativeでこれを行うことはできません。

+10

これは本当の答えです –

+16

ES6の方法: 'const formBody = Object.keys(詳細).map(key => encodeURIComponent(key)+ '=' +エンコードURI(詳細)[key]))join( '&');' –

+0

URLSearchParams https://github.com/WebReflection/url-search-paramsのpolyfillは、ネイティブまたはそれ以前のブラウザで動作する可能性があります。 – bucabay

3

使用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'); 
+0

これは、php7がFormDataのエンコードを解析していないため、意図した通りです。 PHP –

+0

-1の男の子と女の子の投票が増える; URLSearchParamsはReact Nativeに存在しない(https://github.com/facebook/react-native/issues/9596を参照)。 –

-1

あなたはもっと簡単に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 
}) 
+1

-1; JSONについてはあなたが話していますが、実際にはオブジェクトをエンコーディングしています。さらに、 'Object.prototype'を拡張することは悪いことです。拡張がライブラリで定義された同じ名前のプロパティと競合する可能性があるからです。 w ECMAScript自体の将来のバージョンによって、orse。 –

関連する問題