534

以下のコードでは、AngularJS$httpメソッドがURLを呼び出し、xsrfオブジェクトを「リクエストペイロード」として送信します(Chromeデバッガーの[ネットワーク]タブで説明されています)。jQuery$.ajaxメソッドは同じ呼び出しを行いますが、xsrfを「フォームデータ」として送信します。

AngularJSにリクエストペイロードではなくフォームデータとしてxsrfを送信させるにはどうすればよいですか?

var url = 'http://somewhere.com/';
var xsrf = {fkey: 'xsrf key'};

$http({
    method: 'POST',
    url: url,
    data: xsrf
}).success(function () {});

$.ajax({
    type: 'POST',
    url: url,
    data: xsrf,
    dataType: 'json',
    success: function() {}
});
4

21 に答える 21

624

渡される $http オブジェクトに次の行を追加する必要があります。

headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}

渡されたデータは、URL エンコードされた文字列に変換する必要があります。

> $.param({fkey: "key"})
'fkey=key'

したがって、次のようなものがあります。

$http({
    method: 'POST',
    url: url,
    data: $.param({fkey: "key"}),
    headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
})

から: https://groups.google.com/forum/#!msg/angular/5nAedJ1LyO0/4Vj_72EZcDsJ

アップデート

AngularJS V1.4 で追加された新しいサービスを使用するには、次を参照してください。

于 2012-07-11T23:31:37.627 に答える
194

ソリューションで jQuery を使用したくない場合は、これを試すことができます。ここから解決策をつかみましたhttps://stackoverflow.com/a/1714899/1784301

$http({
    method: 'POST',
    url: url,
    headers: {'Content-Type': 'application/x-www-form-urlencoded'},
    transformRequest: function(obj) {
        var str = [];
        for(var p in obj)
        str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
        return str.join("&");
    },
    data: xsrf
}).success(function () {});
于 2013-02-14T06:04:49.330 に答える
83

私は他のいくつかの答えを取り、少しきれいなものを作りました.config().app.jsのangular.moduleの最後にこの呼び出しを置きます:

.config(['$httpProvider', function ($httpProvider) {
  // Intercept POST requests, convert to standard form encoding
  $httpProvider.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
  $httpProvider.defaults.transformRequest.unshift(function (data, headersGetter) {
    var key, result = [];

    if (typeof data === "string")
      return data;

    for (key in data) {
      if (data.hasOwnProperty(key))
        result.push(encodeURIComponent(key) + "=" + encodeURIComponent(data[key]));
    }
    return result.join("&");
  });
}]);
于 2013-10-28T11:39:15.783 に答える
58

AngularJS v1.4.0 の時点で、ドキュメント ページ$httpParamSerializerに記載されているルールに従って、任意のオブジェクトを HTTP 要求の一部に変換する組み込みサービスがあります。

次のように使用できます。

$http.post('http://example.com', $httpParamSerializer(formDataObj)).
    success(function(data){/* response status 200-299 */}).
    error(function(data){/* response status 400-999 */});

正しいフォーム投稿のためには、Content-Typeヘッダーを変更する必要があることに注意してください。すべての POST リクエストに対してこれをグローバルに行うには、次のコード (Albireo の半分の回答から取得) を使用できます。

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

現在の投稿に対してのみこれを行うにheadersは、リクエスト オブジェクトのプロパティを変更する必要があります。

var req = {
 method: 'POST',
 url: 'http://example.com',
 headers: {
   'Content-Type': 'application/x-www-form-urlencoded'
 },
 data: $httpParamSerializer(formDataObj)
};

$http(req);
于 2015-06-01T19:57:20.907 に答える
24

動作をグローバルに定義できます。

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

したがって、毎回再定義する必要はありません。

$http.post("/handle/post", {
    foo: "FOO",
    bar: "BAR"
}).success(function (data, status, headers, config) {
    // TODO
}).error(function (data, status, headers, config) {
    // TODO
});
于 2012-11-21T09:32:49.810 に答える
9

以下のソリューションで試すことができます

$http({
        method: 'POST',
        url: url-post,
        data: data-post-object-json,
        headers: {'Content-Type': 'application/x-www-form-urlencoded'},
        transformRequest: function(obj) {
            var str = [];
            for (var key in obj) {
                if (obj[key] instanceof Array) {
                    for(var idx in obj[key]){
                        var subObj = obj[key][idx];
                        for(var subKey in subObj){
                            str.push(encodeURIComponent(key) + "[" + idx + "][" + encodeURIComponent(subKey) + "]=" + encodeURIComponent(subObj[subKey]));
                        }
                    }
                }
                else {
                    str.push(encodeURIComponent(key) + "=" + encodeURIComponent(obj[key]));
                }
            }
            return str.join("&");
        }
    }).success(function(response) {
          /* Do something */
        });
于 2013-10-09T11:00:31.043 に答える
8

post 用のアダプター サービスを作成します。

services.service('Http', function ($http) {

    var self = this

    this.post = function (url, data) {
        return $http({
            method: 'POST',
            url: url,
            data: $.param(data),
            headers: {'Content-Type': 'application/x-www-form-urlencoded'}
        })
    }

}) 

コントローラーなどで使用します。

ctrls.controller('PersonCtrl', function (Http /* our service */) {
    var self = this
    self.user = {name: "Ozgur", eMail: null}

    self.register = function () {
        Http.post('/user/register', self.user).then(function (r) {
            //response
            console.log(r)
        })
    }

})
于 2016-05-16T23:41:34.713 に答える
7
var fd = new FormData();
    fd.append('file', file);
    $http.post(uploadUrl, fd, {
        transformRequest: angular.identity,
        headers: {'Content-Type': undefined}
    })
    .success(function(){
    })
    .error(function(){
    });

チェックアウトしてください! https://uncorkedstudios.com/blog/multipartformdata-file-upload-with-angularjs

于 2015-04-29T10:14:13.373 に答える
7

これおよびその他の関連するものについて説明した非常に優れたチュートリアルがあります - Submitting AJAX Forms: The AngularJS Way

基本的には、POST リクエストのヘッダーを設定して、フォーム データを URL エンコードされた文字列として送信していることを示し、データを同じ形式で送信するように設定する必要があります。

$http({
  method  : 'POST',
  url     : 'url',
  data    : $.param(xsrf),  // pass in data as strings
  headers : { 'Content-Type': 'application/x-www-form-urlencoded' }  // set the headers so angular passing info as form data (not request payload)
});

ここでは、データを文字列にシリアル化するために jQuery の param() ヘルパー関数が使用されていますが、jQuery を使用しない場合は手動でも実行できます。

于 2014-07-02T12:33:34.227 に答える
3

現在、AngularJS Google グループで見つけた次のソリューションを使用しています。

$http
.post('/echo/json/', 'json=' + encodeURIComponent(angular.toJson(データ)), {
    ヘッダー: {
        'Content-Type': 'application/x-www-form-urlencoded; 文字セット=UTF-8'
    }
}).success(関数(データ) {
    $scope.data = データ;
});

PHP を使用している場合は、Symfony 2 HTTP コンポーネントのようなものを使用してこれを読み取る必要があることに注意してください。Request::createFromGlobals()これは、$_POST が自動的にロードされないためです。

于 2013-10-15T23:02:22.053 に答える
3

Content-Type を設定するだけでは不十分です。送信前にフォーム データを URL エンコードします。 $http.post(url, jQuery.param(data))

于 2013-10-01T06:32:47.187 に答える
2

AngularJS は、http-request ヘッダー内で次の content-type を実行しているため、正しく実行されています。

Content-Type: application/json

私のようにphpを使用している場合、またはSymfony2を使用している場合でも、ここで説明されているように、json標準のサーバー互換性を単純に拡張できます: http://silex.sensiolabs.org/doc/cookbook/json_request_body.html

Symfony2 の方法 (例: DefaultController 内):

$request = $this->getRequest();
if (0 === strpos($request->headers->get('Content-Type'), 'application/json')) {
    $data = json_decode($request->getContent(), true);
    $request->request->replace(is_array($data) ? $data : array());
}
var_dump($request->request->all());

利点は、jQuery パラメータを使用する必要がなく、AngularJS のネイティブな方法でそのようなリクエストを実行できることです。

于 2013-07-22T10:27:08.790 に答える
1

あなたのアプリの設定で -

$httpProvider.defaults.transformRequest = function (data) {
        if (data === undefined)
            return data;
        var clonedData = $.extend(true, {}, data);
        for (var property in clonedData)
            if (property.substr(0, 1) == '$')
                delete clonedData[property];

        return $.param(clonedData);
    };

あなたのリソースリクエストで -

 headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            }
于 2015-06-14T17:46:43.203 に答える
0

これは直接的な答えではなく、デザインの方向性が少し異なります。

データをフォームとしてではなく、サーバー側オブジェクトに直接マップされる JSON オブジェクトとして投稿するか、REST スタイルのパス変数を使用します。

XSRFキーを渡そうとしているので、どちらのオプションもあなたのケースには適していない可能性があることがわかりました。このようなパス変数へのマッピングはひどい設計です:

http://www.someexample.com/xsrf/{xsrfKey}

/login本質的に、xsrf キーを他のパス/book-appointmentなどにも渡したいため、きれいな URL を台無しにしたくないためです。

興味深いことに、オブジェクト フィールドとして追加することも適切ではありません。これは、サーバーに渡す各 json オブジェクトでフィールドを追加する必要があるためです。

{
  appointmentId : 23,
  name : 'Joe Citizen',
  xsrf : '...'
}

ドメイン オブジェクトとの直接的なセマンティック アソシエーションを持たない別のフィールドをサーバー側クラスに追加したくないことは確かです。

私の意見では、xsrf キーを渡す最善の方法は、HTTP ヘッダーを使用することです。多くの xsrf 保護サーバー側 Web フレームワーク ライブラリがこれをサポートしています。たとえば Java Spring では、X-CSRF-TOKENheaderを使用して渡すことができます。

JS オブジェクトを UI オブジェクトにバインドする Angular の優れた機能により、フォームをまとめて投稿するという慣習をなくし、代わりに JSON を投稿できるようになります。JSON はサーバー側オブジェクトに簡単にデシリアライズでき、マップ、配列、ネストされたオブジェクトなどの複雑なデータ構造をサポートします。

フォーム ペイロードに配列を投稿するにはどうすればよいですか? 多分このように:

shopLocation=downtown&daysOpen=Monday&daysOpen=Tuesday&daysOpen=Wednesday

またはこれ:

shopLocation=downtwon&daysOpen=Monday,Tuesday,Wednesday

どちらもデザインがイマイチ…

于 2015-02-26T11:37:38.660 に答える