私は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¶m2=value2¶m3=value3
私が当たっているエンドポイントはJSONではなくリクエストパラメータを期待しています。それで、私の質問は、JSONの代わりにjavascriptオブジェクトをリクエストパラメータとして送信するように$http.post
に指示することができるかどうかということです。はい、私はオブジェクトから自分自身で文字列を構築することができることを知っています、しかし私はAngularが箱から出してこれのために何かを提供するかどうか知りたいです。
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
});
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¶m2=value2
として正しくシリアル化し、/requesturl
Content-Typeヘッダーを付けてapplication/x-www-form-urlencoded; charset=utf-8
に送信します。これは通常、エンドポイントでのPOST要求で予想されるとおりです。
AngularJSのドキュメントから:
params - {Object。} - URLの後で?key1 = value1&key2 = value2に変換される文字列またはオブジェクトのマップ。 値が文字列ではない場合、JSON化されます。
そのため、パラメータとして文字列を指定します。そうしたくない場合は、変換を使用してください。繰り返しますが、ドキュメントから:
これらの変換をローカルでオーバーライドするには、configオブジェクトのtransformRequestおよび/またはtransformResponseプロパティとして変換関数を指定します。デフォルトの変換をグローバルにオーバーライドするには、$ httpProviderの$ httpProvider.defaults.transformRequestおよび$ httpProvider.defaults.transformResponseプロパティをオーバーライドします。
詳しくは ドキュメント を参照してください。
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をページに含める必要があります。
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
});
$ 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日かかりました。
これはちょっとしたハックかもしれませんが、この問題を回避し、サーバー側でjsonをPHPのPOST配列に変換しました。
$_POST = json_decode(file_get_contents('php://input'), true);
デフォルトのヘッダーを変更します。
$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);
.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 () {});
}
]);
迅速な調整 - transformRequest関数のグローバル設定に問題がある人のために、Cannot read property 'jquery' of undefined
エラーを取り除くために私が使用しているスニペットを以下に示します。
$httpProvider.defaults.transformRequest = function(data) {
return data != undefined ? $.param(data) : null;
}
サーバーのコードを変更することなく、$http.post
呼び出しのヘッダーを変更し、$_POST
を通常の方法で使用することなく、この問題を解決することもできます。ここで説明: http://victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/
私はこの全体の何度も問題のある行動を見つけました。私は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
コンテンツタイプを指定することも重要です。
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
}
);