jQueryを使ったAjax通信(クロスドメイン編)
jQueryでのAjaxについては実案件でもポツポツ使ってましたが、Ajax呼び出し元とサーバーが同じドメインのケースばっかりで、
サーバーのドメインが異なるケースについては詳しくなかったので、再確認しました。
業務系Webシステムを作ってるとあまり使わない気がしないでも無いですが、例えば他システムのWebAPIをAjaxで呼んだりするかもしれません。
あと、PhoneGapを使う場合は必須になるのではないでしょうか。
以下、サンプルを記述しました。
サーバー側プログラムはSAStrutsですが、他言語でも内容はほとんど変わらないと思います。
サーバー側プログラム
@Execute(validator=false) public String normalAjax() { String data = "{\"id\" : \"A001\",\"name\" : \"山田太郎\"}"; ResponseUtil.write(data); return null; }
HTML側
$.ajax({ url : 'normalAjax', success : function(data) { var jsonData = $.parseJSON(data); alert(jsonData.name); }, error : function(data) { alert('Error!'); }, complete : function(data) { } });
HTMLとサーバーが同じドメインで動作していれば、これで問題なく動作するはずです。
しかし例えばHTMLファイルをディスクに保存してそこから実行すると、うまくいかなくなります。
(当然、urlの変更が必要です。)
JSONPで解決するパターン
JSONPを使う場合、ajaxの呼び出しを下記のように変更します。
HTML側
$.ajax({ url : 'http://localhost:8080/xxx/jsonpAjax', dataType : 'jsonp', success : function(data) { alert(data.name); }, error : function(data) { alert('Error!'); }, complete : function(data) { } });
サーバー側も、JSONPとしてのレスポンスを返すようになっている必要があります。
@Execute(validator=false) public String jsonpAjax() { String data = request.getParameter("callback") + "({\"id\" : \"A001\",\"name\" : \"山田太郎\"});"; ResponseUtil.write(data); return null; }
HTMLからjQuery経由でアクセスすると、こんな形でレスポンスが返って来ます。
jQuery1710505071623176485_1332744836123({"id" : "A001","name" : "山田太郎"});
これで、HTMLとサーバーが別ドメインでも結果を取得することができます。
Access-Control-Allow-Originヘッダーで解決するパターン
レスポンスヘッダーにAccess-Control-Allow-Originを指定することで、別ドメインのサーバーにAjaxでアクセスすることができるようになります。
HTML側
$.ajax({ url : 'http://localhost:8080/xxx/acaoAjax', success : function(data) { var jsonData = $.parseJSON(data); alert(jsonData.name); }, error : function(data) { alert('Error!'); }, complete : function(data) { } });
HTML側は、通常のAjaxと同じです。
サーバー側プログラム
@Execute(validator=false) public String acaoAjax() { response.setHeader("Access-Control-Allow-Origin","*"); String data = "{\"id\" : \"A001\",\"name\" : \"山田太郎\"}"; ResponseUtil.write(data); return null; }
レスポンスヘッダーの1行を加えるだけで、HTMLとサーバーが別ドメインでも結果を取得することができます。
ただ、Access-Control-Allow-Originは全てのブラウザーが対応しているわけではないようで、IE6とかIE7では使えませんでした。
こちら(XMLHttpRequest level2に対応しているブラウザまとめ at HouseTect, JavaScriptな情報をあなたに)を参考にさせていただきました。
まとめ
○クロスドメインでのAjax通信をする場合、サーバー側での設定が必要
これはセキュリティ上仕方のないことです。
サーバープログラムの実装を自分で作るときはJSONPかACAOかを選択できると思いますが、いずれにしろ
通信するデータの中身と使い方について十分注意する必要がありそうです。