수색…


소개

원격지 주소가 스크립트 원본 과 동일하지 않은 경우 스크립트가 원격 컨텐트에 액세스 할 수 없도록 웹 브라우저에서 동일한 원본 정책을 사용합니다. 이렇게하면 악의적 인 스크립트가 다른 웹 사이트에 중요한 데이터를 얻기 위해 요청을 수행하는 것을 방지 할 수 있습니다.

두 URL의 출처 는 두 URL이 동일한 프로토콜 , 호스트 이름포트를 갖는 경우 동일한 것으로 간주됩니다.

동일 출처 정책을 우회하는 방법

클라이언트 측 JavaScript 엔진 (브라우저 내부에서 실행되는 엔진)에 관한 한 현재 도메인 이외의 소스에서 컨텐츠를 요청하는 데 사용할 수있는 직접적인 솔루션이 없습니다. (그런데이 제한은 Node JS와 같은 JavaScript- 서버 도구에는 존재하지 않습니다.)

그러나 다음과 같은 방법을 사용하여 다른 소스에서 데이터를 검색하는 것이 가능합니다 (경우에 따라). 일부는 솔루션 생산 시스템 대신에 해킹이나 해결 방법을 제시 할 수 있습니다.

방법 1 : CORS

오늘날 대부분의 공용 API는 개발자가 CORS (Cross-Origin Resource Sharing)라는 기능을 사용하여 클라이언트와 서버간에 양방향으로 데이터를 보낼 수 있도록합니다. 브라우저는 특정 HTTP 헤더 ( Access-Control-Allow-Origin )가 설정되어 있고 요청 사이트의 도메인이 헤더 값에 나열되어 있는지 확인합니다. 그렇다면 브라우저가 AJAX 연결을 설정할 수 있습니다.

그러나 개발자는 다른 서버의 응답 헤더를 변경할 수 없기 때문에이 방법을 항상 신뢰할 수있는 것은 아닙니다.

방법 2 : JSONP

JSON with P 추가는 대개 일시적인 해결책으로 비난됩니다. 가장 직접적인 방법은 아니지만 여전히 작업이 완료됩니다. 이 방법은 모든 도메인에서 스크립트 파일을로드 할 수 있다는 이점을 이용합니다. 그러나 외부 소스에서 JavaScript 코드를 요청하는 것은 항상 잠재적 인 보안 위험이며, 더 나은 솔루션이 있으면 일반적으로 피해야합니다.

JSONP를 사용하여 요청 된 데이터는 일반적으로 JavaScript에서 객체 정의에 사용되는 구문에 맞는 JSON 이므로 전송 방법이 매우 간단합니다. JSONP를 통해 얻은 외부 데이터를 웹 사이트가 사용하게하는 일반적인 방법은 URL의 GET 매개 변수를 통해 설정된 콜백 함수 내에이 데이터를 래핑하는 것입니다. 외부 스크립트 파일이로드되면 함수가 첫 번째 매개 변수로 데이터와 함께 호출됩니다.

<script>
function myfunc(obj){
    console.log(obj.example_field);
}
</script>
<script src="http://example.com/api/endpoint.js?callback=myfunc"></script>

http://example.com/api/endpoint.js?callback=myfunc 의 내용은 다음과 같습니다.

myfunc({"example_field":true})

이 함수는 항상 먼저 정의되어야하며, 그렇지 않으면 외부 스크립트가로드 될 때 정의되지 않습니다.

메시지와 안전한 원본 교차 통신

window.postMessage() 메서드는 상대 이벤트 처리기 인 window.onmessage 를 사용하여 안전하게 교차 원점 통신을 사용할 수 있습니다.

대상 windowpostMessage() 메소드를 호출하여 다른 window 메시지를 보내면 onmessage 이벤트 핸들러로이를 가로 채고, 처리하고, 필요에 따라 보낸 사람 윈도우에 응답을 보낼 수 있습니다. postMessage() 다시 postMessage() 하십시오.

하위 프레임과 통신하는 창의 예

  • http://main-site.com/index.html 콘텐츠 :

     <!-- ... -->
     <iframe id="frame-id" src="http://other-site.com/index.html"></iframe>
     <script src="main_site_script.js"></script>
     <!-- ... -->
    
  • http://other-site.com/index.html 콘텐츠 :

     <!-- ... -->
     <script src="other_site_script.js"></src>
     <!-- ... -->
    
  • main_site_script.js 콘텐츠 :

     // Get the <iframe>'s window
     var frameWindow = document.getElementById('frame-id').contentWindow;
    
     // Add a listener for a response
     window.addEventListener('message', function(evt) {
         
         // IMPORTANT: Check the origin of the data! 
         if (event.origin.indexOf('http://other-site.com') == 0) {
             
             // Check the response
             console.log(evt.data);
             /* ... */
         }
     });        
    
     // Send a message to the frame's window
     frameWindow.postMessage(/* any obj or var */, '*');
    
  • other_site_script.js 콘텐츠 :

     window.addEventListener('message', function(evt) { 
    
         // IMPORTANT: Check the origin of the data! 
         if (event.origin.indexOf('http://main-site.com') == 0) {
             
             // Read and elaborate the received data
             console.log(evt.data);
             /* ... */
    
             // Send a response back to the main window
             window.parent.postMessage(/* any obj or var */, '*');
         }
     });
    


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow