えいのうにっき

a-knowの日記です

AngularJSの$http.postでパラメータをrequest bodyに含めて送る

こんにちは、a-knowです。 今回も前回に同じく、AngularJSの話題です。

表題の件で、最初は下記のように記述していたのですが、

var parameter = {};
parameter.piyo = 'abc';
parameter.moko = 'xyz';

$http({
    method : 'POST',
    url : '/api/hogeFuga',
    params: parameter
}).success(function(data, status, headers, config) {
    //成功
}).error(function(data, status, headers, config) {
    //失敗
});

これだと、リクエストURLが「http://a-know-home.appspot.com/api/hogeFuga?piyo=abc&moko=xyz」で「request bodyが空」のPOSTリクエストになってしまいます。 サーバ側がslim3のasString()とかを使って実装してたので、最初は気が付かなかった・・・^^;

そこで、AngularJSのAPIリファレンスをちょっと見なおして、下記のように修正してみる。

var parameter = {};
parameter.piyo = 'abc';
parameter.moko = 'xyz';

$http({
    method : 'POST',
    url : '/api/hogeFuga',
    data: parameter
}).success(function(data, status, headers, config) {
    //成功
}).error(function(data, status, headers, config) {
    //失敗
});

「params」としていたところを「data」にしました。 これでうまくいくだろう・・・と思ったら、ところが今度は、 リクエストURLが「http://a-know-home.appspot.com/api/hogeFuga」、request bodyに「{"piyo":"abc","moko":"xyz"}」というJSONが入ったPOSTリクエストに・・・。 ぬうう、なんという余計なお世話親切設計・・・!!

で、色々探した結果、下記のURLに行き着きました。

AngularJS - Any way for $http.post to send request parameters instead of JSON? - stackoverflow

今回の例だと、下記のようにすればOK。

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

$http({
    method : 'POST',
    url : '/api/hogeFuga',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
    transformRequest: transform,
    data: parameter
}).success(function(data, status, headers, config) {
    //成功
}).error(function(data, status, headers, config) {
    //失敗
});

transformという変換用の関数を宣言しておいて、それをtransformRequestオプションで指定。 それと、ヘッダにContent-Typeを上記のように設定。これでうまくいきます。

ただこれだと、各POSTリクエスト毎に上記のような書き方をすることに注意しなくちゃいけなくて、このことを把握している人ならまだいいけれど、そうではない人がコードを追加したりするときのことを考えると、危なっかしい。 そこで、下記のようにcontrollerを設定するmoduleに対してtransformRequest関数を指定しておいてやると、各POSTリクエスト毎にtransformRequestオプションを指定する必要がなくなる。

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

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

〜

$http({
    method : 'POST',
    url : '/api/hogeFuga',
    data: parameter
}).success(function(data, status, headers, config) {
    //成功
}).error(function(data, status, headers, config) {
    //失敗
});

これはいいですね!

関連エントリ

blog.a-know.me

AngularJSリファレンス

AngularJSリファレンス

Webアプリ構築のためのAngularJS

Webアプリ構築のためのAngularJS

follow us in feedly