>웹 프론트엔드 >JS 튜토리얼 >일반적인 자바스크립트 도메인 간 통신 방법_자바스크립트 기술

일반적인 자바스크립트 도메인 간 통신 방법_자바스크립트 기술

WBOY
WBOY원래의
2016-05-16 15:22:231587검색

이 글에서는 주로 몇 가지 일반적인 JavaScript 크로스 도메인 통신 방법을 소개합니다. 먼저 JSONP에 대해 설명해보세요.
1. JSONP
JSONP(JSON with Padding)는 주류 브라우저의 도메인 간 데이터 액세스 문제를 해결하는 데 사용할 수 있는 JSON의 "사용 모드"입니다. 동일 출처 정책으로 인해 일반적으로 server1.example.com에 위치한 웹 페이지는 HTML 3f1c4e4b6b16bbbd69b2ee476dc4f83a 요소를 제외하고 server1.example.com 이외의 서버와 통신할 수 없습니다. 3f1c4e4b6b16bbbd69b2ee476dc4f83a 요소의 이러한 공개 정책을 사용하면 웹 페이지는 다른 소스에서 동적으로 생성된 JSON 데이터를 얻을 수 있으며 이러한 사용 패턴을 JSONP라고 합니다. JSONP로 캡처된 데이터는 JSON이 아니라 JSON 파서로 구문 분석하는 대신 JavaScript 인터프리터로 실행되는 임의의 JavaScript입니다.
다음으로 JSONP의 구체적인 구현을 소개하겠습니다.
우리는 크로스 도메인 js 파일의 코드(물론 웹 스크립트 보안 정책을 준수함)의 코드라도 웹 페이지가 무조건 실행될 수 있다는 것을 알고 있습니다. 원격 서버 Remoteserver.com의 루트 디렉터리에 다음 코드가 포함된 Remote.js 파일이 있습니다.
alert('나는 원격 파일입니다')
로컬 서버 localserver.com에는 다음과 같은 jsonp.html 페이지 코드가 있습니다.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
 <title></title> 
 <script type="text/javascript" src="http://remoteserver.com/remote.js"></script> 
</head> 
<body> 
 
</body> 
</html>

페이지에 도메인 간 호출이 성공했음을 알리는 프롬프트 창이 나타날 것이라는 데는 의심의 여지가 없습니다.

이제 jsonp.html 페이지에서 함수를 정의한 다음 원격 remote.js에 데이터를 전달하여 함수를 호출합니다. jsonp.html 페이지 코드는 다음과 같습니다.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
 <title></title> 
 <script type="text/javascript"> 
 var localHandler = function(data){ 
  alert('我是本地函数,可以被跨域的remote.js文件调用,远程js带来的数据是:' + data.result); 
 }; 
 </script> 
 <script type="text/javascript" src="http://remoteserver.com/remote.js"></script> 
</head> 
<body> 
 
</body> 
</html> 

remote.js 파일 코드는 다음과 같습니다.
localHandler({"result":"나는 원격 js에서 가져온 데이터입니다."})
성공적으로 실행한 후에는 도메인 간 원격 데이터 수집의 목적이 달성된 것 같지만 또 다른 질문이 발생합니다. 원격 js가 호출해야 하는 로컬 함수의 이름을 어떻게 알릴 수 있나요? 이때는 서버에서 제공하는 js 스크립트를 동적으로 생성하기만 하면 됩니다. 호출자는 매개변수를 전달하여 서버에 필요한 기능을 알려줄 수 있습니다.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
 <title></title> 
 <script type="text/javascript"> 
 // 得到航班信息查询结果后的回调函数 
 var flightHandler = function(data){ 
  alert('你查询的航班结果是:票价 ' + data.price + ' 元,' + '余票 ' + data.tickets + ' 张。'); 
 }; 
 // 提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码) 
 var url = "http://flightQuery.com/jsonp/flightResult.aspx&#63;code=CA1998&callback=flightHandler"; 
 // 创建script标签,设置其属性 
 var script = document.createElement('script'); 
 script.setAttribute('src', url); 
 // 把script标签加入head,此时调用开始 
 document.getElementsByTagName('head')[0].appendChild(script); 
 </script> 
</head> 
<body> 
 
</body> 
</html> 

이번에는 코드가 많이 변경되었습니다. 더 이상 원격 js 파일을 직접 작성하지 않고 동적 쿼리를 구현하는 코드입니다. 이는 jsonp 클라이언트 구현의 핵심 부분이기도 합니다. jsonp 호출의 전체 과정.
호출 URL에 코드 매개변수가 전달되어 내가 확인하려는 것은 CA1998 항공편의 정보임을 서버에 알려주고, 콜백 매개변수는 내 로컬 콜백 함수가 flightHandler라고 서버에 알리므로 쿼리를 전달하세요. 결과적으로 이 함수 호출이 발생합니다. flightResult.aspx라는 이 페이지는 이와 같은 코드 조각을 생성하여 jsonp.html에 제공합니다(서버 측 구현은 여기서 설명하지 않습니다. 선택한 언어와는 아무 관련이 없습니다. 최종 분석에서는 다음과 같습니다). 문자열을 이어붙이는 것뿐입니다):

flightHandler({ 
 "code": "CA1998", 
 "price": 1780, 
 "tickets": 5 
}); 

flightHandler 함수에 전달되는 것은 비행의 기본 정보를 설명하는 json입니다. 페이지를 실행하면 프롬프트 창이 성공적으로 팝업되고 전체 jsonp 실행 프로세스가 성공적으로 완료됩니다!
하지만 JSONP에는 문제가 있습니다. json 데이터를 패키징하고 명명된 함수를 호출하는 역할을 담당합니다. 이 방법은 보안 위험이 있습니다. JSONP를 사용할 경우 악성 스크립트가 직접 제공하는 데이터를 완전히 신뢰해야 합니다. 우리를 인수하십시오. 따라서 다음에는 이러한 보안 위험을 방지할 수 있는 또 다른 방법을 소개하겠습니다.
2. 코스
CORS(Cross OriginResource Sharing, 교차 출처 리소스 공유)는 교차 출처 XMLHttpRequests를 구현합니다. 교차 출처 HTTP 요청에는 서버에 HTTP 요청의 소스 정보를 제공하는 Origin 헤더가 포함됩니다. 헤더는 브라우저에 의해 보호되며 애플리케이션 코드로 변경할 수 없습니다. 이 접근 방식은 외부 입력을 평가하는 것보다 훨씬 안전합니다.
과거에는 ajax가 동일한 소스에서만 요청을 할 수 있었지만 이제는 XMLHttpRequests 레벨 2를 통해 도메인 간 요청을 할 수 있습니다. 페이지나 애플리케이션이 이미 http://www.test1.com에 있고 http://www.test2.com에서 데이터 추출을 요청할 계획이라고 가정해 보겠습니다. 일반적인 상황에서 AJAX를 직접 사용하여 요청하면 요청이 실패하고 브라우저도 "교차 도메인"이 발생하는 "소스 불일치" 오류를 반환합니다.
CORS를 사용하면 http://www.test2.com은 http://www.test1.com의 요청을 허용하는 헤더를 추가하기만 하면 됩니다. PHP 코드는 다음과 같습니다.

header("Access-Comtrol-Allow-Origin:*");<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> </span> 

여기서 *는 모든 도메인이 당사 서버에 요청을 제출할 수 있음을 의미합니다. 지정된 도메인 이름을 설정할 수도 있으며 코드는 다음과 같습니다.

header("Access-Control-Allow-Origin:http://www.test2.com"); 

设置好头信息之后,其他域就可以进行请求了。
        使用"跨域资源共享"的前提,是浏览器必须支持这个功能,而且服务器端必须同意这种"跨域"。如果能够满足上面的条件,则代码的写法与不跨域的请求完全一样。
xhr.open('GET', ' http://www.test2.com '); 
 接下来介绍另外一种实时通信方式:
3、Cross-document messaging
跨文档信息通信。使用这个功能,只要获取到网页所在窗口对象的实例,不仅同原的web网页可以互相通信,也可以实现跨域通信。要想接受从其他窗口发送来的信息,必须对窗口对象的onmessage事件进行监听,其他窗口可以通过postmessage方法来传递数据,该方法使用两个参数:第一个参数为所发送的消息文本,但也可以是任何js对象,第二个参数为接收消息的对象窗口的url地址。
下面进行试验,主页面index.html代码如下:

<!DOCTYPE html> 
<html> 
 <head> 
  <meta charset="utf-8"> 
  <title></title> 
 </head> 
<script type="text/javascript"> 
 function sendIt(){ 
  document.getElementById("otherPage").contentWindow 
  .postMessage(//向子窗口发出请求 
   document.getElementById("message").value,//值 
   "http://127.0.0.1:8020"//目标域 
  ) 
 } 
</script> 
 <body> 
  <iframe src="http://127.0.0.1:8020/test2/JS/jstest/Cross-document-messaging/other.html" id="otherPage" width="" height=""></iframe> 
  <br /><br /> 
  <input type="text" name="message" id="message" value="" /> 
  <input type="button" name="" id="" value="发送跨域消息" onclick="sendIt();" /> 
 </body> 
</html> 

 窗口所引用页面other.html代码如下:

<!DOCTYPE html> 
<html> 
 <head> 
  <meta charset="utf-8"> 
  <title></title> 
<script type="text/javascript"> 
 window.addEventListener("message",function(event){//通过onmessage监听 
  //将从父窗口传来的数据展现出来 
  document.getElementById("content").innerHTML+=event.data+"<br>"; 
 },false); 
</script> 
 </head> 
 <body> 
  信息来自于另外一个域 
  <div id="content"> 
    
  </div> 
 </body> 
</html>

试验结果如下:


可以看到在81端口服务器中的index.html和8020端口的服务器中的other.html进行的通信。
完整代码如下:

<!DOCTYPE html>
<html>
 <head>
 <meta charset="utf-8">
 <title></title>
 </head>
<script type="text/javascript">
 function sendIt(){
 document.getElementById("otherPage").contentWindow
 .postMessage(//向子窗口发出请求
 document.getElementById("message").value,//值
 "http://127.0.0.1:8020"//目标域
 )
 }
</script>
 <body>
 <iframe src="http://127.0.0.1:8020/test2/JS/jstest/Cross-document-messaging/other.html" id="otherPage" width="" height=""></iframe>
 <br /><br />
 <input type="text" name="message" id="message" value="" />
 <input type="button" name="" id="" value="发送跨域消息" onclick="sendIt();" />
 </body>
</html>

CrossDocumentMessaging_index.html

<!DOCTYPE html>
<html>
 <head>
 <meta charset="utf-8">
 <title></title>
<script type="text/javascript">
 window.addEventListener("message",function(event){//通过onmessage监听
 //将从父窗口传来的数据展现出来
 document.getElementById("content").innerHTML+=event.data+"<br>";
 },false);
</script>
 </head>
 <body>
 信息来自于另外一个域
 <div id="content">
 
 </div>
 </body>
</html>

以上就是本文的全部内容,希望对大家了解熟悉常见的javascript跨域通信方法有所帮助。

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.