JavaScript などのクライアント側プログラミング言語では、同一生成元ポリシーにより、あるドメインのクロスドメイン スクリプトが別のドメインのほとんどのプロパティとメソッドにアクセスして操作できないことが規定されています。 2 つのドメインが同じプロトコル、同じホスト、同じポートを持つ場合にのみ、それらを同じドメインとみなします。ただし、実際の開発では、他のドメインからリソースを取得する必要があることがよくあります。このとき、今日は主にクエリの作業でよく使用されるいくつかのクロスドメイン リソースのメソッドをまとめます。
1.window.name
window オブジェクトの name 属性は、新しいページがフレームにロードされるとき、name 属性値は変更されません。次に、ページ A で iframe を使用して他のドメインのページ B をロードし、ページ B で JavaScript を使用して window.name に渡すデータを割り当てることができます。iframe がロードされた後、アクセスのために name 属性値を取得できます。 Webサービスによって送信される情報。ただし、name 属性は、同じドメイン名を持つフレームにのみアクセスできます。これは、name 属性にアクセスするには、リモート Web サービス ページが読み込まれるときに、フレームを元のドメインに戻す必要があることを意味します。つまり、ページ A が iframe のアドレスを変更して同じドメイン内のアドレスに変更すると、window.name の値を読み出すことができます。 name プロパティを取得したら、フレームを破棄します。この方法は一方向のデータ要求に非常に適しており、プロトコルはシンプルで安全です。
ページ B (www.jesse.com/data.html) のコードは次のとおりです:
<script type="text/javascript"> window.name = 'I was there!'; // 这里是要传输的数据,大小一般为2M,IE和firefox下可以大至32M左右 // 数据格式可以自定义,如json、字符串 </script>
ページ A (www.jack.com/index.html) のコードは次のとおりです:
<script type="text/javascript"> var state = 0, iframe = document.createElement('iframe'), loadfn = function() { if (state === 1) { var data = iframe.contentWindow.name; // 读取数据 console.log(data); //弹出'I wasthere!' (function(){ //获取数据以后销毁这个iframe。 iframe.contentWindow.document.write(''); iframe.contentWindow.close(); document.body.removeChild(iframe); })(); } else if (state === 0) { state = 1; // 设置的代理页面使其回原始域 iframe.contentWindow.location = "http://www.jack.com/proxy.html"; } }; iframe.src = 'http://www.jesse.com/data.html'; if (iframe.attachEvent) { iframe.attachEvent('onload', loadfn); } else { iframe.onload = loadfn; } document.body.appendChild(iframe); </script>
2. src を使用したタグ
ブラウザはデフォルトでクロスドメイン アクセスを禁止していますが、タグの src 属性を使用してページ内の他のドメインのファイルを参照することは禁止されていません。これに基づいて、src 属性を使用してノード メソッドを作成することで、完全なクロスドメイン通信を簡単に実現できます。この原理を使用するいくつかのクロスドメイン方法があります:
スクリプトの動的作成
たとえば、ドメイン A のページ pageA からドメイン B のデータをロードしたい場合、ドメイン B のページ pageB に、 pageA を JavaScript 必須データの形式で宣言し、pageA の script タグを使用して pageB をロードすると、pageB のスクリプトが実行されます。
pageA (www.jack.com/index.html) コードは次のとおりです:
function getData(data){ //这里是对获取的数据的相关操作 console.log(data); //数据获取到后移除创建的script标签 document.body.removeChild(originData); } var originData = document.createElement('script'); originData.src = 'http://www.jesse.com/data.js'; originData.setAttribute("type", "text/javascript"); document.body.appendChild(originData);
pageB (www.jesse.com/data.js) コードは次のとおりです:
getData('这里是远程跨域获取的数据');//数据格式可以自定义,如json、字符串
jsonp
in $.ajax() を使用してリモート データを取得する場合、それがクロスドメイン リソースであれば、jsonp メソッドを使用できます。jsonp は ajax の一種だと思っていましたが、後で気づきました。全く同じものではありません。 Ajax は xhr モードでデータを要求しますが、jsonp はスクリプト モードでデータを要求します。これは上記の動的スクリプトの作成方法と同じです。
pageA (www.jack.com/index.html) コードは次のとおりです:
$.ajax({ //JSONP不支持POST方式 type:"GET", url:"http://www.jesse.com/data.php", dataType:"jsonp", //自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据 jsonpCallback:"getData", success: function(data){ console.log(data); }, error: function(){ console.log('fail'); } })
pageB (www.jesse.com/data.js) コードは次のとおりです:
<?php $callback = $_GET['callback'];//得到回调函数名,这里是getData $data = array('a','b','c');//要返回的数据 echo $callback.'('.json_encode($data).')';//输出 ?>
3.document .domain
メインドメインは同じでサブドメインが異なる例については、document.domainを設定することで解決できます。 具体的な方法は、http://www.php.cn/ と http://www.php.cn/ の 2 つのファイルに document.domain = "a.com" をそれぞれ追加し、a.html ファイルを渡すことです。 iframe を作成して iframe の contentDocument を制御し、2 つの js ファイルが「相互作用」できるようにします。もちろん、この方法で解決できるのは、プライマリ ドメインは同じだがセカンダリ ドメイン名が異なる状況のみです
a.html (www.a.com)
document.domain = 'a.com'; var ifr = document.createElement('iframe'); ifr.src = 'http://script.a.com/b.html'; ifr.style.display = 'none'; document.body.appendChild(ifr); ifr.onload = function(){ var doc = ifr.contentDocument || ifr.contentWindow.document; // 在这里操纵b.html alert(doc.getElementsByTagName("h1")[0].childNodes[0].nodeValue); };
b.html (script.a) .com
document.domain = 'a.com';
4. クロスオリジン リソース共有 (CORS)
原則: クロスオリジン リソース共有 (CORS) は、AJAX がクロスドメイン アクセスを実現できるようにするクロスドメイン アクセス メカニズムを定義します。 CORS を使用すると、あるドメイン上の Web アプリケーションがクロスドメイン AJAX リクエストを別のドメインに送信できるようになります。この機能の実装は、サーバーによって応答ヘッダーを送信するだけで簡単です。クライアント + サーバーの協調宣言を通じてリクエストのセキュリティを確保します。サーバーは、一連の HTTP リクエスト パラメーター (Access-Control-Allow-Origin など) を HTTP リクエスト ヘッダーに追加して、受け入れられるドメイン リクエストとリクエスト タイプを制限します。クライアントは、次の場合に独自に宣言する必要があります。 Origin (Origin)、そうでない場合、クライアントがステートメントを作成しない場合、リクエストはブラウザによって直接インターセプトされ、サーバーに到達しません。 HTTP リクエストを受信した後、サーバーはドメインを比較し、同じドメインからのリクエストのみが処理されます。
pageA (www.jack.com/index.html) コードは次のとおりです:
var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function(){ if(xhr.readyState === 4 && xhr.status === 200){ console.log(xhr.responseText); } }; xhr.open("get","http://www.jesse.com/data.php"); xhr.send(null);
pageB (www.jesse.com/data.php) コードは次のとおりです:
<?php header("Access-Control-Allow-Origin: http://www.php.cn/");//与简单的请求相同 header("Access-Control-Allow-Methods: GET, POST");//允许请求的方法 header("Access-Control-Max-Age: 3628800"); //将这个请求缓存多长时间 $data = array('a','b','c');//要返回的数据 echo json_encode($data);//输出 ?>
5.window.postMesage は一般的には使用されません
window.postMessage(message,targetOrigin) メソッドは、ウィンドウ オブジェクトが同じウィンドウ オブジェクトに属しているかどうかに関係なく、他のウィンドウ オブジェクトにメッセージを送信するために使用できます。現在、IE8+、FireFox、Chrome や Opera などのブラウザはすでに window.postMessage メソッドをサポートしています。
pageA(www.jack.com/index.html) コードは次のとおりです:
<iframe id="proxy" src="http://www.jesse.com/index.html" onload="postMsg()" style="display: none"></iframe> <script type="text/javascript"> var obj = { msg: 'hello world' } function postMsg() { var iframe = document.getElementById('proxy'); var win = iframe.contentWindow; win.postMessage(obj, 'http://www.jesse.com'); } </script> pageB(www.jesse.com/data.php)代码如下: <script type="text/javascript"> window.onmessage = function(e) { console.log(e.data.msg + " from " + e.origin); } </script>
6. location.hash は一般的に使用されません
pageA(www.jack.com/index.html) ) コードは次のとおりです:
function startRequest() { var ifr = document.createElement('iframe'); ifr.style.display = 'none'; ifr.src = 'http://www.jesse.com/b.html#sayHi'; //传递的location.hash document.body.appendChild(ifr); } function checkHash() { try { var data = location.hash ? location.hash.substring(1) : ''; if (console.log) { console.log('Now the data is ' + data); } } catch (e) {}; } setInterval(checkHash, 5000); window.onload = startRequest;
pageA(www.jack.com/proxy.html) コードは次のとおりです:
parent.parent.location.hash = self.location.hash.substring(1);
pageB(www.jesse.com/b.html) コードは次のとおりです:
function checkHash() { var data = ''; //模拟一个简单的参数处理操作 switch (location.hash) { case '#sayHello': data = 'HelloWorld'; break; case '#sayHi': data = 'HiWorld'; break; default: break; } data && callBack('#' + data); } function callBack(hash) { // ie、chrome的安全机制无法修改parent.location.hash,所以要利用一个中间的www.a.com域下的代理iframe var proxy = document.createElement('iframe'); proxy.style.display = 'none'; proxy.src = 'http://www.jack/c.html' + hash; // 注意该文件在"www.jack.com"域下 document.body.appendChild(proxy); } window.onload = checkHash;
以上がこの記事の全内容です。皆さんの学習に役立つことを願っています。また、皆さんも PHP 中国語 Web サイトをサポートしていただければ幸いです。
JavaScript のいくつかのクロスドメイン メソッドに関連するその他の記事については、PHP 中国語 Web サイトに注目してください。