JavaScript와 같은 클라이언트측 프로그래밍 언어에서 동일 출처 정책은 교차 도메인 스크립트가 격리되도록 규정합니다. 한 도메인의 스크립트는 다른 도메인의 대부분의 속성과 메서드에 액세스하고 작동할 수 없습니다. 두 도메인이 동일한 프로토콜, 동일한 호스트, 동일한 포트를 갖는 경우에만 동일한 도메인으로 간주합니다. 그러나 실제 개발에서는 다른 도메인에서 리소스를 얻어야 하는 경우가 많습니다. 이때 다양한 크로스 도메인 리소스 방법이 등장합니다. 오늘은 쿼리 작업에서 일반적으로 사용되는 몇 가지 크로스 도메인 방법을 주로 요약하겠습니다.
1.window.name
window 객체의 name 속성은 프레임에 새 페이지가 로드될 때 name 속성 값이 변경되지 않는 매우 특별한 속성입니다. 그런 다음 페이지 A의 iframe을 사용하여 다른 도메인의 페이지 B를 로드하고, 페이지 B의 JavaScript를 사용하여 window.name에 전달할 데이터를 할당할 수 있습니다. iframe이 로드된 후 액세스를 위해 name 속성 값을 얻을 수 있습니다. 웹 서비스에서 보낸 정보입니다. 그러나 name 속성은 동일한 도메인 이름을 가진 프레임에만 액세스할 수 있습니다. 이는 이름 속성에 액세스하려면 원격 웹 서비스 페이지가 로드될 때 프레임을 원래 도메인으로 다시 탐색해야 함을 의미합니다. 즉, 페이지 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의 페이지 A 페이지에서 도메인 B의 데이터를 로드하려는 경우 도메인 B의 페이지 pageB 이 예에서는 페이지 A에 필요한 데이터를 JavaScript 형식으로 선언한 다음 스크립트 태그를 사용하여 페이지 A에서 페이지 B를 로드하면 페이지 B의 스크립트가 실행됩니다.
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
$.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을 설정하여 해결할 수 있습니다. 구체적인 방법은 document.domain = "a.com"을 각각 http://www.php.cn/ 및 http://www.php.cn/ 두 파일에 추가한 다음 a.html 파일을 전달하는 것입니다. iframe의 contentDocument를 제어하기 위해 iframe을 생성하여 두 js 파일이 "상호작용"할 수 있도록 합니다. 물론 이 방법은 기본 도메인은 같지만 보조 도메인 이름이 다른 상황만 해결할 수 있습니다.
www.a.com의 a.html
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); };
script.a.com의 b.html
document.domain = 'a.com';
4. CORS(교차 출처 리소스 공유)
원칙: CORS(Cross-Origin Resource Sharing)는 AJAX가 도메인 간 액세스를 달성할 수 있도록 하는 도메인 간 액세스 메커니즘을 정의합니다. CORS를 사용하면 한 도메인의 웹 애플리케이션이 도메인 간 AJAX 요청을 다른 도메인에 제출할 수 있습니다. 이 기능을 구현하는 것은 서버에서 응답 헤더를 보내는 것만큼 간단합니다. 클라이언트 + 서버 협업 선언을 통해 요청 보안을 보장합니다. 서버는 일련의 HTTP 요청 매개변수(예: Access-Control-Allow-Origin 등)를 HTTP 요청 헤더에 추가하여 어떤 도메인 요청과 어떤 요청 유형이 허용될 수 있는지 제한하고 클라이언트는 다음과 같은 경우 자체 선언을 해야 합니다. 요청을 시작합니다. 그렇지 않으면 서버가 이를 처리하지 않습니다. 클라이언트가 설명을 하지 않으면 요청이 브라우저에 의해 직접 차단되어 서버에 도달하지 않습니다. 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 ) 메소드는 html5 기능에 새로 도입되었으며, 이를 사용하여 창 개체가 동일한 소스에 속하든 다른 소스에 속하든 관계없이 다른 창 개체에 메시지를 보낼 수 있습니다. 현재 IE8+, FireFox, Chrome, Opera 및 기타 브라우저는 이미 창을 지원합니다. 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. 해시는 일반적으로 사용되지 않습니다
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 중국어 웹사이트를 지지해 주시길 바랍니다.
Javascript의 여러 도메인 간 방법과 관련된 더 많은 기사를 보려면 PHP 중국어 웹사이트를 주목하세요!