2017-10-16 2 views
1

페이지 안에 iframe이 있습니다. 두 도메인 모두 동일한 도메인에서 호스팅됩니다. iframe을 완전히 제어 할 수 있지만 상위 페이지를 제어 할 수는 없습니다.부모 창 컨텍스트에서 iframe에서 Websocket 연결

Image

은 그래서 iframe을에서 웹 소켓 연결을 설정해야하지만, 부모 창 내가 iframe을 탐색하고있어 동안 살아 보관의 맥락에서 (다른 메뉴 항목 상위 페이지). 수 있다는 것이다 B 및 C.

로 이동하면서

A.html에 접속을 수립 (같은 이미지를 참조), 생존 유지?

답변

0

짧은 답변 : 부모 윈도우에

직접 스크립트 삽입은 여전히 ​​더 우아한 해결책이 될 수 있습니다.

긴 대답 :

웹 소켓 서버에 대한 연결의 단지 종류이다. 일단 그것을 생성하면 브라우저의 탭에 남아 있고 websocket을 만든 스크립트를 언로드하면 파괴되지 않습니다. iframe에 WebSocket을을 만드는

두 가지 문제가 :

  1. 당신은 아마 새로운 웹 소켓 연결을 같은 iframe이 컨텐츠를로드 할 때마다 생성하고 싶지 않아요.
  2. iframe이 언로드되면 모든 웹 소켓의 이벤트 핸들러가 손실됩니다 (예 : onopen, onclose, onmessage 등).

기본 창에서 websocket 팩토리를 만들 수 있습니다. 그들이 경우에도 원래의 소스 연결할 수 있도록

  1. 클론 제공하는 웹 소켓 이벤트 핸들러를 iframe을에서 제공하는 데이터를 사용하여 웹 소켓을 만들고 내부 컬렉션 속성에 저장 :이 공장의 인스턴스는 책임이 될 것이다 언로드됩니다. 이벤트 핸들러가 단순하면 잘 작동합니다. 폐쇄가 손실됩니다 - 그들은 iframe을의 스크립트에 정의 외부 폐쇄를 사용하는 경우, 즉 -

기능 복제 몇 가지 알려진 문제가 있습니다. 라이브러리 복제에 대한 조사를 원할 수 있습니다.

main.js (주에로드 된 index.html)

var socketsCollection = new SocketsCollection(); 

function SocketsCollection() { 
    this.collection = {}; 

    this.add = function(key, obj) { 
     if (this.exists(key)) return; 

     // clone websocket event handlers 
     // PS: this is not the best solution to clone a function. Need a better research here 
     eval("var onopen = " + obj.onopen.toString()); 
     eval("var onclose = " + obj.onclose.toString()); 
     eval("var onmessage = " + obj.onmessage.toString()); 

     // create websocket 
     var ws = new WebSocket(obj.url); 
     ws.onopen = function(e) { 
      onopen(e, key, ws); 
     }; 
     ws.onclose = function(e) { 
      onclose(e, key, ws); 
     } 
     ws.onmessage = function(e) { 
      onmessage(e, key, ws); 
     } 

     this.collection[key] = { 
      key: key, 
      ws: ws 
     }; 

     // test websocket is alive 
     var self = this; 
     var counter = 1; 
     window.setInterval(function() { 
      console.log('testing ' + key); 
      self.collection[key].ws.send('ping # ' + counter + ' websocket ' + key); 
      counter++; 
     }, 2000); 
    } 

    this.exists = function(key){ 
     return this.collection[key] !== undefined; 
    } 
} 

iframed.js :

function foo(window, socketKey) { 
    if (window.socketsCollection.exists(socketKey)) return; 

    var newSocketData = { 
     url: "wss://echo.websocket.org/", 
     onopen: function(e, key, ws) { 
      console.log(key + ' is OPEN', ws.readyState) 
      ws.send('Hello socket ' + key); 
     }, 
     onclose: function(e, key, ws) { 
      console.log(key + ' is CLOSED', ws.readyState) 
     }, 
     onmessage: function (e, key, ws) { 
      console.log(key + ' response: ', e.data); 
     } 
    }; 

    window.socketsCollection.add(socketKey, newSocketData); 
} 

을 수행합니다.HTML :

<script src="iframed.js"></script> 
<script> 
    foo.call(window.parent, window.parent, 'A'); 
</script> 

b.html :

<script src="iframed.js"></script> 
<script> 
    foo.call(window.parent, window.parent, 'B'); 
</script>