크로스도메인 window.postMessage()

황제낙엽 2020.07.29 14:53 조회 수 : 303

sitelink1 https://developer.mozilla.org/en-US/docs...ostMessage 
sitelink2 https://ooz.co.kr/232 
sitelink3 https://jjeong.tistory.com/476 
sitelink4 https://blog.naver.com/hs88610/221709466083 
extra_vars4 https://blog.naver.com/hs88610/221709466083 
extra_vars5  
extra_vars6  

The window.postMessage() method safely enables cross-origin communication between Window objects

 

 

Syntax

> targetWindow.postMessage(message, targetOrigin, [transfer]);

 

Example

 

/*

 * In window A's scripts, with A being on <http://example.com:8080>:

 */

var popup = window.open(/* popup details */);

 

// When the popup has fully loaded, if not blocked by a popup blocker:

 

// This does nothing, assuming the window hasn't changed its location.

popup.postMessage("The user is 'bob' and the password is 'secret'", "https://secure.example.net");

 

// This will successfully queue a message to be sent to the popup, assuming

// the window hasn't changed its location.

popup.postMessage("hello there!", "http://example.com");

 

function receiveMessage(event)

{

  // Do we trust the sender of this message?  (might be

  // different from what we originally opened, for example).

  if (event.origin !== "http://example.com")

    return;

 

  // event.source is popup

  // event.data is "hi there yourself!  the secret response is: rheeeeet!"

}

window.addEventListener("message", receiveMessage, false);

 

/*

 * In the popup's scripts, running on <http://example.com>:

 */

 

// Called sometime after postMessage is called

function receiveMessage(event)

{

  // Do we trust the sender of this message?

  if (event.origin !== "http://example.com:8080")

    return;

 

  // event.source is window.opener

  // event.data is "hello there!"

 

  // Assuming you've verified the origin of the received message (which

  // you must do in any case), a convenient idiom for replying to a

  // message is to call postMessage on event.source and provide

  // event.origin as the targetOrigin.

  event.source.postMessage("hi there yourself!  the secret response " + "is: rheeeeet!", event.origin);

}

 

window.addEventListener("message", receiveMessage, false);

 

 

그리고 popup 또는 iframe의 타겟페이지가 있는 서버의 web.xml에 다음과 같은 설정이 필요하다

 

<filter>

  <filter-name>CorsFilter</filter-name>

  <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>

  <init-param>

    <param-name>cors.allowed.origins</param-name>

    <param-value>http://아이피:포트</param-value> <!-- 호출페이지가 위치한 서버의 도메인 주소

  </init-param>

  <init-param>

    <param-name>cors.allowed.methods</param-name>

    <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>

  </init-param>

  <init-param>

    <param-name>cors.allowed.headers</param-name>

    <param-value>Pragma,Expires,If-Modified-Since,Cache-Control,Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>

  </init-param>

  <init-param>

    <param-name>cors.exposed.headers</param-name>

    <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials,</param-value>

  </init-param>

  <init-param>

    <param-name>cors.support.credentials</param-name>

    <param-value>true</param-value>

  </init-param>

  <init-param>

    <param-name>cors.preflight.maxage</param-name>

    <param-value>10</param-value>

  </init-param>

</filter>

<filter-mapping>

  <filter-name>CorsFilter</filter-name>

  <url-pattern>/*</url-pattern>

</filter-mapping>

 

또는, 타겟서버의 CGI페이지에서 다음과 같이 Response의 Header를 설정해도 된다

 

response.setHeader("Access-Control-Allow-Headers", "accept, cache-control, content-type, expires, if-modified-since, pragma, x-requested-with");

response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS, HEAD") ; // CORS에서 허용하는 메소드

response.setHeader("Access-Control-Max-Age", "3600"); // CORS가 유효한 시간

response.setHeader("Access-Control-Allow-Origin", "*"); // CORS를 허용하는 Origin

response.setHeader("Access-Control-Allow-Credentials", "true");

 

그리고 타겟페이지에서는 다음과 같이 스크립트를 작성한다

 

<script type="text/javascript">

    var retValue = "";

    

     window.onload = function() {

         if (window.addEventListener) {  // all browsers except IE before version 9

             window.addEventListener ("message", OnMessage, false);

         }

         else {

             if (window.attachEvent) {   // IE before version 9

                 window.attachEvent("onmessage", OnMessage);     // Internet Explorer from version 8

             }

         }

    }

 

    function OnMessage (event) {

        // Check the location of the caller

        // Opera earlier than version 10

        if ('domain' in event) {

            alert("event.domain-"+event.domain);

            if (event.domain != "http://172.10.12.11:9290") { //허용할 도메인 주소(호출페이지)

                return;

            }

        }

 

        // Firefox, Safari, Google Chrome, Internet Explorer from version 8 and Opera from version 10

        if ('origin' in event) {

            alert("event.origin-"+event.origin);

            if (event.origin != "http://172.10.12.11:9290") { //허용할 도메인 주소(호출페이지)

                return;

            }

        }

        

        message = '잘 받았습니다'; //회신할 메세지

        message = event.data + message;

        event.source.postMessage (message, event.origin);

    }

</script>

 

호출페이지에서는 타겟페이지의(iframe) window객체의 postMessage()를 호출하면서 데이터를 전달할 수 있다