Ajaxでjsonをクロスドメインで取得する

http://programchan.com/archives/82
前回記事からの続きになりますが、まず最初にAjaxって何なのかの説明を上げておきます。とは言ってもwikipediaそのままですが

Ajax(エイジャックス、アジャックス、アヤックス)は、ウェブブラウザ内で非同期通信とインターフェイスの構築などを行う技術の総称。XMLHttpRequestHTTP通信を行うためのJavaScript組み込みクラス)による非同期通信を利用し、通信結果に応じてダイナミックHTMLで動的にページの一部を書き換えるというアプローチを取る。

実際にAjax処理を作成してテストを行っていると実行が出来ない状況があると思います。エラーを見てみるとクロスドメインになっていて実行失敗していることがありますよね。

クロスドメインとは

Aajxによるサーバとの通信は元となるブラウザを表示しているサイトと同一ドメインでなければ通信が出来ない、これがクロスドメイン制約になります。
同一ドメインと通信を行っているうちはいいんですがWebApiとして公開などを行いだした場合には同一ではないドメインとの通信をすることが多くなるかと思います。
AndroidやIPhoneによる通信を行う場合なども該当すると思います。

クロスドメインの場合のAjax通信

方法としては複数あります

  • jsonpを使用する
  • Access-Control-Allow-Originを設定する
  • XDomainRequestを使用する

Jsonpを使用する

jQuery.getJSON('http://example.com/search.json?callback=?',
    {
        'hoge': 'fuga'
    },
    function (data) {
        console.log(data);
    }
});

Access-Control-Allow-Originを設定する

これはサーバサイドの設定になります

<?php
    header('Access-Control-Allow-Origin: *');
    header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept');
    // CakePHPの場合
    $this->header('Access-Control-Allow-Origin: *');
    $this->header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept');
# Railsの場合
config.action_dispatch.default_headers = {
    'Access-Control-Allow-Credentials' => 'true',
    'Access-Control-Allow-Origin' => 'http://localhost:9000',
    'Access-Control-Request-Method' => '*'
}

XDomainRequestを使用する

// IE8,9でXMLHttpRequestの代わりにXDomainRequestを使う
(function( jQuery ) {
if ( window.XDomainRequest ) {
    jQuery.ajaxTransport(function( s ) {
        if ( s.crossDomain && s.async ) {
            if ( s.timeout ) {
                s.xdrTimeout = s.timeout;
                delete s.timeout;
            }
            var xdr;
            return {
                send: function( _, complete ) {
                    function callback( status, statusText, responses, responseHeaders ) {
                        xdr.onload = xdr.onerror = xdr.ontimeout = xdr.onprogress = jQuery.noop;
                        xdr = undefined;
                        complete( status, statusText, responses, responseHeaders );
                    }
                    xdr = new XDomainRequest();
                    xdr.open( s.type, s.url );
                    xdr.onload = function() {
                        callback( 200, "OK", { text: xdr.responseText }, "Content-Type: " + xdr.contentType );
                    };
                    xdr.onerror = function() {
                        callback( 404, "Not Found" );
                    };
                    xdr.onprogress = function() {};
                    if ( s.xdrTimeout ) {
                        xdr.ontimeout = function() {
                            callback( 0, "timeout" );
                        };
                        xdr.timeout = s.xdrTimeout;
                    }
                    xdr.send( ( s.hasContent && s.data ) || null );
                },
                abort: function() {
                    if ( xdr ) {
                        xdr.onerror = jQuery.noop();
                        xdr.abort();
                    }
                }
            };
        }
    });
}
})( jQuery );
jQuery.getJSON('http://example.com/search.json',
    {
        'hoge': 'piyo'
    },
    function (data) {
        console.log(data);
    }
});
[amazonjs asin=”4774144665″ locale=”JP” title=”JavaScript本格入門 ?モダンスタイルによる基礎からAjax・jQueryまで”]

Follow me!