2012-06-12 6 views
4

나는 많은 클라이언트 측 데이터 다운로드와 처리를 수행하는 앱을 만들고 있습니다. 데이터 처리는 하위 도메인에있는 iframe에서 처리되어 기본 앱과 분리됩니다. 데이터를 다운로드하는 것은이 iframe입니다. 의사 소통은 postMessage를 통해 이루어집니다.같은 도메인에있는 다른 창 사이에서 통신하기

더 나은 점만 제외하면 모든 것이 잘 작동합니다.

사용자가 추가 탭/창을 열면 앱이 현재 모든 데이터를 다시로드하고 중복 처리 작업을 수행 할 수도 있습니다.이 작업은 모든 작업이 느려지고로드하는 데 시간이 오래 걸리는 문제 이외의 문제는 아닙니다.

내가하고 싶은 것은 각 최상위 탭/창에서 iframe 처리 중 하나와 통신하는 것입니다.이 창은 원래 창을 닫으면 다시 열 수 있습니다. 문제는 자바 스크립트를 통해 열리지 않지만 일반 브라우저 메소드를 통해 탭에서 링크를 열면 메시지를 보내는 데 필요한 iframe에 대한 참조를 얻을 수 없다는 것입니다.

어쨌든 iframe에 대한 창 참조를 다른 탭에 전달하여 postMessage를 통해 통신 할 수 있습니까? 이것이 공유 된 근로자를 통해 어느정도 달성 ​​될 수 있습니까?

전체 처리 작업에 공유 된 작업자를 사용할 수 있다는 것을 알았지 만 데이터가 작업자 내부에서 액세스 할 수없는 제 3 자 도메인에서 발생하므로 자체 문제가 발생할 수 있습니다.

모든 주요 브라우저의 최신 버전과의 호환성 만 필요합니다.

편집 : SharedWorker가 아직 파이어 폭스에서 구현되지 않았다는 것을 발견했습니다. 따라서 작동하지 않을 것입니다. 이걸 얻을 수있는 다른 방법은 없나요?

편집 2 : 난 당신이 사용할 수 있다는 것을 발견했습니다

var win = window.open('', 'my_window_name'); 

다른 창에서 iframe이에 대한 참조를 캡처. iframe이 아직 존재하지 않으면 창으로 열립니다. 즉시 닫힌 경우에도 깜박임이 발생하고 '팝업 차단됨'메시지가 표시되어 사용할 수 없게됩니다.

+0

웹 근로자는 IE 10에서만 작동하므로 옵션이 아닌 것 같습니다 .-) –

+0

html5 localstorage를 사용할 수 있습니까? – pahnin

+0

그리고 javascript를 사용하여 – pahnin

답변

2

다른 사람이이를 발견하면 솔루션을 제안했습니다. 그것은 다소 해킹되어 더 테스트가 필요합니다. 그러나 지금까지는 효과가 있습니다. 필요한 경우 교차 도메인에서 작동합니다.

두 가지 트릭을 조합하여 사용합니다.

윈도우에 대한 참조를 가져

remote_window = window.open("", "remote_window_name"); 

을 사용하는 것이다. 이것은 주어진 이름으로 윈도우가 이미 열려있는 경우 새 윈도우를 열지 않고 참조가 반환되기 때문에 작동합니다.

그러나 iframe이 존재하지 않으면 새 창이 팝업된다는 문제가 있습니다. 이를 방지하기 위해 로컬 저장소가 사용됩니다. 창/탭이로드되면 localStorage를 검사하여 이미 공유 iframe이있는 다른 페이지가 있는지 확인합니다. 그렇지 않은 경우 iframe을 삽입하고 로컬 저장소에 플래그를 설정하여 사용 가능하다고 설정합니다.

마지막 도랑 리조트로, 창이 여전히 열리면 try 블록을 사용하여 새로 열린 창을 닫습니다. try 블록은 도메인 간 오류를 방지합니다.이것은 최악의 상황은 사용자가 팝업 창이 나타나고 사라지는 것을 보게되거나 '팝업 활성화'메시지가 표시된다는 것을 의미합니다. 나는 아직 테스트에서 이것을 유발하도록 관리하지 못했습니다. 이것은 극단적 인 경우입니다.

try { 
    if(store_window.location.href === "about:blank"){ 
     remote_window.close(); 
     remote_window = insertIfame(); 
    } 
} catch(err) { 
} 

onunload 이벤트가 추가되어 페이지가 닫힐 때 플래그가 제거됩니다.

또한 시간 초과 플래그를 지속적으로 새로 고치는 setInterval이 만들어집니다. 나는 그것을 초당 4 번 돌린다. 두 번째 창/탭이로드되면 iframe 플래그가 통신을 시도하기 전에 시간 초과되지 않았는지 확인합니다. 이는 작은 오버 헤드이지만 두 번째 iframe로드가 발생하는 비용보다 훨씬 적습니다. 이것은 브라우저가 충돌하거나 onunload가 어떤 이유로 든 실행되지 않으면 부실 데이터를 방지하기위한 목적으로 사용됩니다. 메인 윈도우가 루프에 갇혀있는 경우 타임 아웃 (현재 1 초)을 확인할 때 약간의 여유를 포함합니다. 여유 시간은 플래그를 완전히 제거하는 언로드 이벤트가 아닌 시간 초과에만 적용됩니다.

iframe이있는 원래 창이 닫힌 경우에 대비하여 메시지를 보낼 때마다 플래그를 확인해야합니다. 이 때 iframe은 필요한 첫 번째 열린 창에서 다시 삽입되고 플래그는 다시 설정됩니다.

메시지를 쉽게 보낼 수 있습니다. receiveMessage의 event.source 속성 (이 지점을 송신 창에 사용하기 만하면됩니다.)

마지막으로 고려해야 할 한 가지 주요 사례는 기본 창이 닫히는 동안 iframe이 보조 창이있는 중간 프로세스 인 경우입니다. 이론적으로 iframe에서 onunload 이벤트를 사용하여 처리중인 데이터가있는 모든 창으로 메시지를 보내면 처리 할 수 ​​있습니다. 하지만 아직 구현하지 못했고 페이지가 언로드되기 전에 끝나지 않을 수 있습니다. 그것을 다루는 또 다른 방법은 플래그를 확인하고 재 시도하는 2 차 창에서 시간 초과를하는 것입니다. 메시지에 이미 시간 초과가 첨부되어 있으므로이 라우트로 이동합니다.

관련 문제