web-dev-qa-db-ja.com

AngularJS - $ http.postがJSONの代わりにリクエストパラメータを送信する方法はありますか?

私はAJAX POSTリクエストを jQueryのpostメソッド を通して作っているような古いコードをいくつか持っています。この:

$.post("/foo/bar", requestData,
    function(responseData)
    {
        //do stuff with response
    }

requestDataは、いくつかの基本的な文字列プロパティを持つ単なるJavaScriptオブジェクトです。

Angularを使用するように移行中です。この呼び出しを$ http.postに置き換えます。私は以下のことを思いついた。

$http.post("/foo/bar", requestData).success(
    function(responseData) {
        //do stuff with response
    }
});

私がこれをしたとき、私はサーバーから500エラー応答を得ました。 Firebugを使用して、これがリクエストボディを次のように送信したことがわかりました。

{"param1":"value1","param2":"value2","param3":"value3"}

成功したjQueryの$.postはこのように本文を送ります:

param1=value1&param2=value2&param3=value3

私が当たっているエンドポイントはJSONではなくリクエストパラメータを期待しています。それで、私の質問は、JSONの代わりにjavascriptオブジェクトをリクエストパラメータとして送信するように$http.postに指示することができるかどうかということです。はい、私はオブジェクトから自分自身で文字列を構築することができることを知っています、しかし私はAngularが箱から出してこれのために何かを提供するかどうか知りたいです。

116
dnc253

params設定パラメータは本文ではなく文字列をURLに追加するのでここでは機能しないと思いますが、Infeligoがここで提案したものに追加するのはデフォルト変換のグローバルオーバーライドの例です(jQuery ---を使用する param データをパラメータ文字列に変換する例として)。

グローバルtransformRequest関数を設定します。

var app = angular.module('myApp');

app.config(function ($httpProvider) {
    $httpProvider.defaults.transformRequest = function(data){
        if (data === undefined) {
            return data;
        }
        return $.param(data);
    }
});

このようにして、$ http.postへのすべての呼び出しは、本体をjQueryの$.post呼び出しで使用されるのと同じparam形式に自動的に変換します。

呼び出しごとにContent-Typeヘッダーを設定するか、グローバルに次のように設定することもできます。

$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';

呼び出しごとの非グローバルtransformRequestのサンプル:

    var transform = function(data){
        return $.param(data);
    }

    $http.post("/foo/bar", requestData, {
        headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
        transformRequest: transform
    }).success(function(responseData) {
        //do stuff with response
    });
140
Gloopy

Angular> = 1.4を使用する場合、これが私が見つけた最も明確な解決策です。

angular.module('yourModule')
  .config(function ($httpProvider, $httpParamSerializerJQLikeProvider){
    $httpProvider.defaults.transformRequest.unshift($httpParamSerializerJQLikeProvider.$get());
    $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8';
});

そして、あなたはあなたのアプリのどこでもこれをすることができます:

$http({
  method: 'POST',
  url: '/requesturl',
  data: {
    param1: 'value1',
    param2: 'value2'
  }
});

そして、それはデータをparam1=value1&param2=value2として正しくシリアル化し、/requesturl Content-Typeヘッダーを付けてapplication/x-www-form-urlencoded; charset=utf-8に送信します。これは通常、エンドポイントでのPOST要求で予想されるとおりです。

21
Saeb Amini

AngularJSのドキュメントから:

params - {Object。} - URLの後で?key1 = value1&key2 = value2に変換される文字列またはオブジェクトのマップ。 値が文字列ではない場合、JSON化されます。

そのため、パラメータとして文字列を指定します。そうしたくない場合は、変換を使用してください。繰り返しますが、ドキュメントから:

これらの変換をローカルでオーバーライドするには、configオブジェクトのtransformRequestおよび/またはtransformResponseプロパティとして変換関数を指定します。デフォルトの変換をグローバルにオーバーライドするには、$ httpProviderの$ httpProvider.defaults.transformRequestおよび$ httpProvider.defaults.transformResponseプロパティをオーバーライドします。

詳しくは ドキュメント を参照してください。

17
Infeligo

JQueryの$.param関数を使用してrequestDataのJSONデータをシリアル化します。

手短に言えば、あなたのコードと同じようなコードを使用します。

$http.post("/foo/bar",
$.param(requestData),
{
    headers:
    {
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
    }
}
).success(
    function(responseData) {
        //do stuff with response
    }
});

これを使用するためには、AngularJSと共にjQueryをページに含める必要があります。

15
Sagar Bhosale

Angular 1.4以降、jQueryを使用せずにフォームデータをシリアル化できることに注意してください。

App.jsで、

module.run(function($http, $httpParamSerializerJQLike) {
  $http.defaults.transformRequest.unshift($httpParamSerializerJQLike);
});

それからあなたのコントローラーで:

$http({
    method: 'POST',
    url: myUrl',
    headers: {'Content-Type': 'application/x-www-form-urlencoded'},
    data: myData
});
7
Thomas Graziani

$ resourceがリクエストをキャッシュするので、私はカスタムhttp認証の設定にも問題があります。

うまく機能させるには、これを実行して既存のヘッダを上書きする必要があります。

var transformRequest = function(data, headersGetter){
  var headers = headersGetter();
  headers['Authorization'] = 'WSSE profile="UsernameToken"';
  headers['X-WSSE'] = 'UsernameToken ' + nonce
  headers['Content-Type'] = 'application/json';
};

return $resource(
  url,
    {
    },
    {
      query: {
        method: 'POST',
        url: apiURL + '/profile',
        transformRequest: transformRequest,
        params: {userId: '@userId'}
      },
    }
);

私は誰かを助けることができたと思います。これを理解するのに3日かかりました。

5
Frank Marcelo

これはちょっとしたハックかもしれませんが、この問題を回避し、サーバー側でjsonをPHPのPOST配列に変換しました。

$_POST = json_decode(file_get_contents('php://input'), true);
5
TimoSolo

デフォルトのヘッダーを変更します。

$http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded;charset=utf-8";

次に、JQueryの$.paramメソッドを使います。

var payload = $.param({key: value});
$http.post(targetURL, payload);
4
Zags
   .controller('pieChartController', ['$scope', '$http', '$httpParamSerializerJQLike', function($scope, $http, $httpParamSerializerJQLike) {
        var data = {
                TimeStamp : "2016-04-25 12:50:00"
        };
        $http({
            method: 'POST',
            url: 'serverutilizationreport',
            headers: {'Content-Type': 'application/x-www-form-urlencoded'},
            data: $httpParamSerializerJQLike(data),
        }).success(function () {});
    }
  ]);
3
Rohit Luthra

迅速な調整 - transformRequest関数のグローバル設定に問題がある人のために、Cannot read property 'jquery' of undefinedエラーを取り除くために私が使用しているスニペットを以下に示します。

$httpProvider.defaults.transformRequest = function(data) {
        return data != undefined ? $.param(data) : null;
    }
2
kshep92

サーバーのコードを変更することなく、$http.post呼び出しのヘッダーを変更し、$_POSTを通常の方法で使用することなく、この問題を解決することもできます。ここで説明: http://victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/

1
vikramaditya234

私はこの全体の何度も問題のある行動を見つけました。私はexpress(タイピングなし)とbodyParser(dt〜body-parserタイピング)からそれを使いました。

私はファイルをアップロードしようとはしませんでした。代わりに単に投稿文字列で与えられたJSONを解釈するために。

request.bodyは単に空のjson({})でした。

多くの調査の後、ついにこれは私のために働きました:

import { json } from 'body-parser';
...
app.use(json()); <-- should be defined before the first POST handler!

クライアント側からの要求文字列でapplication/jsonコンテンツタイプを指定することも重要です。

0
peterh

AngularJS v1.4.8 +(v1.5.0)の構文

       $http.post(url, data, config)
            .then(
                    function (response) {
                        // success callback
                    },
                    function (response) {
                        // failure callback
                    }
            );

例えば:

    var url = "http://example.com";

    var data = {
        "param1": "value1",
        "param2": "value2",
        "param3": "value3"
    };

    var config = {
        headers: {
            'Content-Type': "application/json"
        }
    };

    $http.post(url, data, config)
            .then(
                    function (response) {
                        // success callback
                    },
                    function (response) {
                        // failure callback
                    }
            );
0
Pranav V R