JavaScriptのクロスドメイン制限を突破する
JavaScriptはJSファイルが置いてある以外のドメインのファイルをセキュリティの関係上、参照出来ない仕様になっています。
よく他ドメインのXMLなどを参照したいときなどこの壁にぶつかりますね。。
この問題を解決する方法はおもに3つあります。
PHPやCGIを経由する
これは"JavaScript"→"PHP or CGI"→"参照したいファイル"という順に読み込んでいきます。
設定がとても簡単で一番一般的な方法かもしれません。
CGI等が使用出来る環境でなければならないのが条件です。
XMLを読み込む前提で記述例です。
<?php if(isset($_GET["url"])) readfile($_GET["url"]); ?>
$(function(){ $.ajax({ url:'ajax.php', async: true, cache: false, type:'GET', dataType:'xml', error: function(){ //読み込みに失敗時の処理 }, success: function(xml){ //読み込みに終了後の処理 } }); });
Flashを経由する
Flashを経由するとCGIやPHPが使えない環境でも動作するメリットがあります。
がしかし、"crossdomain.xml"という設定ファイルを読み込みたいデータが置いてあるサーバ側に置かなければなりません。
サーバ管理者でない場合はリスト登録をお願いをすると言うような事が必要になってきます。
crossdomain.xml
<?xml version="1.0"?> <!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd"> <cross-domain-policy> <site-control permitted-cross-domain-policies="メタポリシー設定" /> <allow-access-from domain="外部ファイルを読み込む方のドメイン" /> </cross-domain-policy>
メタポリシー設定
- all: すべてのポリシーファイルが許可されます。
- by-content-type: Content-Typeがtext/x-cross-domain-policyのすべてのポリシーファイルが許可されます。
- by-ftp-filename: FTPサーバにのみ使用できます。
- master-only: マスターポリシーファイル( /crossdomain.xmlにあります)のみが許可されます。
- none: ポリシーファイルは許可されません。
- none-this-response: HTTP応答ヘッダでのみ指定できる特別なメタポリシー。
ドメインの指定
- 完全なドメイン名 (例:www.example.co.jp )
- IP アドレス (例:65.57.83.12 )
- ワイルドカードを使用したドメイン名 (例:*.example.co.jp )
- 完全なワイルドカード:* (アスタリスクひとつ)
※この場合、すべてのドメイン、および IP アドレスからのアクセスが許可される。
追記 2011/7/6
flashで受け取ったXMLをflashで処理せずJavaScriptに渡そう(無駄?)とすると以下のようになります。
"crossdomain.xml"が相手サーバーに置いてあるのが前提です。
actionscript(3.0)
import flash.external.ExternalInterface; var url_loader : URLLoader = new URLLoader(); var url : URLRequest = new URLRequest("読み込みたいXMLのURL"); url_loader.load(url); url_loader.addEventListener (Event.COMPLETE,LoaderInfoCompleteFunc); function LoaderInfoCompleteFunc (event : Event) { var xml : XML = new XML(url_loader.data); ExternalInterface.addCallback("as_function", xml_display); function xml_display():String { return xml; } }
上記記述の
var url : URLRequest = new URLRequest("読み込みたいXMLのURL");
で読み込みたいXMLのURLを絶対パスで記入してください。また、
ExternalInterface.addCallback("as_function", xml_display);
での、"as_function"はJavaScript側からの呼び出し関数名で、呼び出された際に"xml_display"でXMLの内容を返しています。
function display(){ var flash = document.as3 || window.as3; alert(flash.as_function()); }
上記の記述の
var flash = document.as3 || window.as3;
ででは、クロスブラウザをさせるためのもので変数"flash"のなかに、
IEは"object"タグにid="as3"を設定して、"window.as3"で指定しています。
他ブラウザは"embed"タグに name="as3"を設定して、"document.as3"で指定しています。
alert(flash.as_function());
変数"flash"に入れられたオブジェクトに"as_function()"を実行しています。
これはActionScript側で設定したJavaScriptからの呼び出し用関数名です。
HTML
<object id="as3" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" type="application/x-shockwave-flash" data="sample_03.swf" width="1" height="1"> <param name="movie" value="sample_03.swf"> <embed name="as3" src="sample_03.swf" width="1" height="1"></embed> </object> <input type="button" onclick="display()" value="click!">
上記HTMLではXMLを読み込ませるためのswfを配置してボタンを押すと"display()"を実行します。
JSONPを使う
JSON(JavaScript Object Notation)は、JavaScriptのオブジェクト用の表記をしたデータ形式です。
JavaScriptからは最も利用しやすいデータ形式ですが標準的なファイル形式はXMLな気がします。
このJSON形式をコールバック関数の中にいれた形がJSONP(JSON with Padding)です。
<?php //getjsonp.php if(isset($_GET["url"]) && isset($_GET["cb"])){ header("Content-type: text/javascript;"); echo $_GET["cb"]."( { data : '"; echo str_replace("'","\'", str_replace("\n","\\n",file_get_contents($_GET["url"]))); //ファイルを読込み、改行は\\nに変換、クォートをエスケープ。 echo "'});"; } ?>
//動的に呼び出す関数 function clickGetJSONP( a ) { var url = "http://hogehoge.com/getjsonp.php?cb=hoge&url=http://.....?a="+a; var sc = document.createElement("script"); sc.setAttribute("type","text/javascript"); sc.setAttribute("src", url ); document.getElementsByTagName("body").item(0).appendChild(sc); } //コールバック関数 function hoge( myData) { //取得したデータの処理、例えばid="hoge"にそのまま表示させる場合は document.getElementById("hoge").innerHTML = myData.data; }
2011/7/6 「Flashを経由する」の項目を一部追記しました。
記事元:WebTips