탭 또는 창 간의 통신
흔적을 남기지 않고 브라우저(CORS가 아닌 같은 도메인)에서 여러 탭이나 창을 주고받는 방법을 찾고 있었습니다.몇 가지 솔루션이 있었습니다.
첫 번째 방법은 아마도 최악의 해결책일 것입니다.현재 창에서 창을 열고 창을 열어 두어야만 통신할 수 있습니다.어느 하나의 창에서 페이지를 새로고침하면 대부분의 경우 통신이 끊어집니다.
post Message를 사용하는 두 번째 접근법은 아마도 크로스 오리진 통신을 활성화하지만 첫 번째 접근법과 동일한 문제를 겪습니다.창 개체를 유지 관리해야 합니다.
세 번째 방법은 쿠키를 사용하여 브라우저에 일부 데이터를 저장하는 것입니다.이러한 데이터는 같은 도메인의 모든 창에 메시지를 보내는 것처럼 보일 수 있지만 문제는 정리하기 전에 모든 탭이 이미 "메시지"를 읽었는지 여부를 알 수 없다는 것입니다.쿠키를 정기적으로 읽으려면 일종의 타임아웃을 실행해야 합니다.또한 쿠키의 최대 길이인 4KB로 제한됩니다.
네 번째 솔루션은 localStorage를 사용하여 쿠키의 한계를 극복하고 이벤트를 청취할 수도 있습니다.사용 방법은 승인된 답변에 설명되어 있습니다.
2018년에도 승인된 답변은 여전히 유효하지만, 최신 브라우저용 새로운 솔루션인 Broadcast Channel이 있습니다.브로드캐스트채널을 사용하여 탭 간에 메시지를 쉽게 전송하는 방법에 대한 간단한 예는 다른 답변을 참조하십시오.
이 경우 브로드캐스트채널을 사용하는 것이 좋습니다.아래의 다른 답변을 참조하십시오.그러나 탭 간 통신에 로컬 스토리지를 사용하는 경우에는 다음과 같이 하십시오.
탭이 다른 탭으로 메시지를 보낼 때 알림을 받으려면 '스토리지' 이벤트에 바인딩하기만 하면 됩니다.모든 탭에서 다음을 수행합니다.
$(window).on('storage', message_receive);
★★message_receivelocalStorage를 선택합니다.이벤트 리스너에는 localStorage로 새로 설정된 데이터도 포함되어 있으므로 localStorage 개체 자체를 구문 분석할 필요도 없습니다.설정 직후에 값을 리셋 해 트레이스를 효과적으로 소거할 수 있기 때문에, 이것은 매우 편리합니다.메시지 기능은 다음과 같습니다.
// use local storage for messaging. Set message in local storage and clear it right away
// This is a safe way how to communicate with other tabs while not leaving any traces
//
function message_broadcast(message)
{
localStorage.setItem('message',JSON.stringify(message));
localStorage.removeItem('message');
}
// receive message
//
function message_receive(ev)
{
if (ev.originalEvent.key!='message') return; // ignore other keys
var message=JSON.parse(ev.originalEvent.newValue);
if (!message) return; // ignore empty msg or msg reset
// here you act on messages.
// you can send objects like { 'command': 'doit', 'data': 'abcd' }
if (message.command == 'doit') alert(message.data);
// etc.
}
따라서 탭이 onstorage 이벤트에 바인딩되고 다음 두 가지 기능이 구현되면 다음과 같은 다른 탭으로 메시지를 브로드캐스트할 수 있습니다.
message_broadcast({'command':'reset'})
동일한 메시지를 두 번 전송하면 한 번만 전파되므로 메시지를 반복해야 할 경우 다음과 같은 고유한 식별자를 추가합니다.
message_broadcast({'command':'reset', 'uid': (new Date).getTime()+Math.random()})
또한 메시지를 브로드캐스트하는 현재 탭은 메시지를 실제로 수신하지 않고 동일한 도메인의 다른 탭 또는 창만 수신합니다.
사용자가 다른 웹 페이지를 로드하거나 setItem() 호출 직후에 탭을 닫으면 removeItem()이 발생할 수 있습니다. 제가 테스트한 , , 가, 제, 라, 라, 라, 라, 라, 라, well, well, well까지 언로딩을 보류하고 .message_broadcast()닫혔어요.매우 긴 for() 사이클을 넣으려고 테스트했는데도 사이클이 끝날 때까지 기다렸다가 닫힙니다.사용자가 중간에 탭을 닫으면 브라우저는 메시지를 디스크에 저장할 시간이 부족하기 때문에 이 방법은 트레이스 없이 메시지를 보내는 안전한 방법처럼 보입니다.
이를 위한 최신 API가 있습니다 - Broadcast Channel
다음과 같이 간단합니다.
var bc = new BroadcastChannel('test_channel');
bc.postMessage('This is a test message.'); /* send */
bc.onmessage = function (ev) { console.log(ev); } /* receive */
메시지가 단순히 DOMString일 필요는 없습니다.어떤 종류의 오브젝트라도 송신할 수 있습니다.
아마도 API의 청결성과는 별개로 오브젝트 문자열화가 없는 것이 이 API의 주요 장점일 것입니다.
현재는 Chrome 및 Firefox에서만 지원되지만 localStorage를 사용하는 polyfill을 찾을 수 있습니다.
jQuery를 기반으로 하지 않은 솔루션을 찾는 사용자는 Thomas M이 제공하는 솔루션의 일반 JavaScript 버전을 참조하십시오.
window.addEventListener("storage", message_receive);
function message_broadcast(message) {
localStorage.setItem('message',JSON.stringify(message));
}
function message_receive(ev) {
if (ev.key == 'message') {
var message=JSON.parse(ev.newValue);
}
}
체크아웃 Across Tabs - 크로스 오리진 브라우저 탭 간에 쉽게 통신할 수 있습니다.postMessage API와 sessionStorage API를 조합하여 통신을 훨씬 쉽고 안정적으로 만듭니다.
다양한 접근법이 있으며 각각 장단점이 있습니다.각각에 대해 설명하겠습니다.
-
장점:
- 웹 스토리지는 단순히 쿠키의 향상으로 볼 수 있으며, 훨씬 더 큰 스토리지 용량을 제공합니다.Mozilla 소스 코드를 보면 5120KB(5MB, Chrome에서는 250만 문자와 동일)가 도메인 전체의 기본 스토리지 크기임을 알 수 있습니다.따라서 일반적인 4KB 쿠키보다 훨씬 더 많은 공간을 사용할 수 있습니다.
- 데이터는 모든 HTTP 요청(HTML, 이미지, JavaScript, CSS 등)에 대해 서버로 전송되지 않으므로 클라이언트와 서버 간의 트래픽 양이 줄어듭니다.
- localStorage에 저장된 데이터는 명시적으로 삭제될 때까지 유지됩니다.변경 내용은 저장되며 현재 및 향후 모든 사이트 방문에 사용할 수 있습니다.
단점:
-
장점:
- 다른 거에 비해 AFAIK가 없어요.
단점:
- 이름, 값, 유효기간 등을 포함한 쿠키 전체의 상한은 4KB입니다.대부분의 브라우저를 지원하려면 이름을 4000바이트 미만으로 유지하고 전체 쿠키 크기를 4093바이트 미만으로 유지하십시오.
- 데이터는 모든 HTTP 요청(HTML, 이미지, JavaScript, CSS 등)에 대해 서버로 반환되므로 클라이언트와 서버 간의 트래픽 양이 증가합니다.
일반적으로 다음 사항이 허용됩니다.
- 총 300개의 쿠키
- 쿠키당 4096바이트
- 도메인당 20개의 쿠키
- 도메인당 81920바이트(최대 크기 4096=81920바이트의 쿠키 20개 지정)
-
장점:
- 와와다 it it it to .
localStorage. - 변경은 창(또는 Chrome 및 Firefox와 같은 브라우저의 탭)별로만 사용할 수 있습니다.변경 내용이 저장되고 현재 페이지와 같은 창에서 사이트에 대한 향후 방문에 사용할 수 있습니다.창을 닫으면 저장소가 삭제됩니다.
단점:
- 데이터는 설정된 창/탭 내에서만 사용할 수 있습니다.
- 데이터는 영구적이지 않습니다. 즉, 창/탭을 닫으면 데이터가 손실됩니다.
- 맘에 들다
localStorage, tt 는 같은 패킷정책으로 동작합니다.따라서 저장된 데이터는 동일한 원본에서만 사용할 수 있습니다.
- 와와다 it it it to .
-
장점:
단점:
- 현재 창에서 창을 열고 창을 열어 두어야 합니다.
- 보안상의 문제 - postMessage를 통해 문자열을 전송하면 다른 JavaScript 플러그인에 의해 퍼블리시된 다른 postMessage 이벤트를 픽업할 수 있으므로 반드시 구현해야 합니다.
targetOrigin메시지 리스너에게 전달되는 데이터의 건전성 체크.
Post Message + Session Storage 조합
postMessage를 사용하여 여러 탭 간에 통신하고 동시에 새로 열린 모든 탭/창에서 sessionStorage를 사용하여 전달되는 데이터를 유지합니다.탭/창이 열려 있는 한 데이터는 유지됩니다.따라서 오프너 탭/창이 닫히더라도 열려 있는 탭/창은 새로고침 후에도 전체 데이터를 보유하게 됩니다.
이를 위해 CrossTabs라는 이름의 JavaScript 라이브러리를 작성했습니다.이 라이브러리는 postMessage API를 사용하여 크로스 오리진 탭/윈도우와 sessionStorage 간에 통신하여 열려 있는 탭/윈도우 ID를 존속하는 데 사용됩니다.
브라우저 탭과 창 사이에 메시지를 보내기 위한 라이브러리 sysend.js를 만들었습니다.라이브러리에 외부 종속성이 없습니다.
동일한 브라우저와 도메인에 있는 탭/윈도우 간의 통신에 사용할 수 있습니다.라이브러리는 Broadcast Channel(지원되는 경우) 또는 localStorage의 스토리지 이벤트를 사용합니다.
API는 매우 간단합니다.
sysend.on('foo', function(data) {
console.log(data);
});
sysend.broadcast('foo', {message: 'Hello'});
sysend.broadcast('foo', "hello");
sysend.broadcast('foo', ["hello", "world"]);
sysend.broadcast('foo'); // empty notification
브라우저가 Broadcast Channel을 지원하면 리터럴오브젝트가 전송됩니다(그러나 실제로는 브라우저에 의해 자동시리얼라이즈 됩니다).지원되지 않을 경우 먼저 JSON으로 시리얼화되고 다른 쪽 끝에서 시리얼화 해제됩니다.
최신 버전에는 도메인 간 통신용 프록시를 만들기 위한 도우미 API도 있습니다(대상 도메인에 단일 HTML 파일이 필요합니다).
또한 새로운 버전은 도메인 간 통신도 지원합니다.proxy.html 상의 및 콜 " " " " "proxy「 」의 「 」의 「 」
sysend.proxy('https://target.com');
(proxy.html은 라이브러리에서 스크립트태그가 1개밖에 없는 매우 단순한 HTML 파일입니다).
양방향 통신을 원할 경우 다른 도메인에서도 동일한 작업을 수행해야 합니다.
메모: local Storage를 사용하여 동일한 기능을 구현하는 경우 Internet Explorer에 문제가 있습니다.스토리지 이벤트는 동일한 창으로 전송되며, 이로 인해 이벤트가 트리거되며, 다른 브라우저의 경우 다른 탭/창에서만 호출됩니다.
사람들이 고려해야 할 또 다른 방법은 공유 근로자들이다.최첨단 개념인 것은 알지만 로컬 스토리지보다 훨씬 빠르고 부모/자녀 창 간의 관계가 필요 없는 릴레이를 공유 작업자에 생성할 수 있습니다.
이에 대한 자세한 내용은 여기를 참조하십시오.
같은 기원의 탭/윈도우 간에 동기화하고 통신하기 위한 작은 오픈 소스 컴포넌트가 있습니다(해임자 - 저는 기여자 중 한 명입니다!).localStorage.
TabUtils.BroadcastMessageToAllTabs("eventName", eventDataString);
TabUtils.OnBroadcastMessage("eventName", function (eventDataString) {
DoSomething();
});
TabUtils.CallOnce("lockname", function () {
alert("I run only once across multiple tabs");
});
추신: 이벤트가 거의 동시에 발생할 때 웹 소켓 연결에서 "Lock/mutex/sync" 컴포넌트의 대부분이 실패하기 때문에 여기서 실례를 무릅쓰고 추천했습니다.
공식 Broadcastchannel과 동일한 기능을 하는 모듈을 만들었지만 로컬 스토리지, 인덱스 데이터베이스 및 unix-sockets에 기반한 폴백을 가지고 있습니다.이를 통해 웹워커 또는 Node.js에서도 항상 작동합니다.pubkey 참조:브로드캐스트채널
제 블로그에 이런 기사를 썼어요.세션 공유브라우저 탭에 데이터를 저장합니다.
라이브러리를 사용하여storageManager다음과 같이 할 수 있습니다.
storageManager.savePermanentData('data', 'key'): //saves permanent data
storageManager.saveSyncedSessionData('data', 'key'); //saves session data to all opened tabs
storageManager.saveSessionData('data', 'key'); //saves session data to current tab only
storageManager.getData('key'); //retrieves data
다른 시나리오에도 대응할 수 있는 편리한 방법이 있습니다.
이것은 개발입니다.storageTomas M이 Chrome에 대해 한 답변의 일부입니다.청취자를 추가해야 합니다.
window.addEventListener("storage", (e)=> { console.log(e) } );
저장소의 아이템을 로드/저장해도 이 이벤트는 실행되지 않습니다.다음 방법으로 수동으로 트리거해야 합니다.
window.dispatchEvent( new Event('storage') ); // THIS IS IMPORTANT ON CHROME
이제 열려 있는 모든 탭이 이벤트를 수신합니다.
언급URL : https://stackoverflow.com/questions/28230845/communication-between-tabs-or-windows
'source' 카테고리의 다른 글
| jQuery 문자 영역의 커서 위치 설정 (0) | 2023.01.26 |
|---|---|
| 로거 메시지에서 JUnit 아사트를 실행하는 방법 (0) | 2023.01.26 |
| MariaDB 설치로 Mysql 데이터베이스가 이동되었습니다. (0) | 2023.01.26 |
| bs4.FeatureNotFound: 요청한 기능을 가진 트리 빌더를 찾을 수 없습니다.lxml파서 라이브러리를 설치해야 합니까? (0) | 2023.01.26 |
| JPA 저장소의 다른 테이블에서 데이터 선택 (0) | 2023.01.26 |