수색…
소개
원격지 주소가 스크립트 원본 과 동일하지 않은 경우 스크립트가 원격 컨텐트에 액세스 할 수 없도록 웹 브라우저에서 동일한 원본 정책을 사용합니다. 이렇게하면 악의적 인 스크립트가 다른 웹 사이트에 중요한 데이터를 얻기 위해 요청을 수행하는 것을 방지 할 수 있습니다.
두 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
를 사용하여 안전하게 교차 원점 통신을 사용할 수 있습니다.
대상 window
의 postMessage()
메소드를 호출하여 다른 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 */, '*'); } });