교차 출처 postMessage가 IE10에서 깨졌습니까?
나는 사소한 postMessage
예제 를 만들려고 노력하고 있습니다 ...
- IE10에서
- 창 / 탭 간 (vs. iframe)
- 기원을 넘어
이 조건 중 하나를 제거하면 잘 작동합니다. :-)
그러나 내가 말할 수있는 한, 윈도우 사이는 postMessage
두 윈도우가 원점을 공유 할 때만 IE10에서 작동하는 것처럼 보입니다. (사실 이상하게도 행동은 그것보다 약간 더 관대합니다. 호스트 를 공유하는 두 가지 다른 출처 도 작동 하는 것 같습니다).
문서화 된 버그입니까? 해결 방법이나 기타 조언이 있습니까?
(참고 : 이 질문 은 문제에 관한 것이지만 대답 은 10이 아닌 IE8 및 IE9에 관한 것 입니다.)
자세한 내용 + 예 ...
런처 페이지 데모
<!DOCTYPE html>
<html>
<script>
window.addEventListener("message", function(e){
console.log("Received message: ", e);
}, false);
</script>
<button onclick="window.open('http://jsbin.com/ameguj/1');">
Open new window
</button>
</html>
시작된 페이지 데모
<!DOCTYPE html>
<html>
<script>
window.opener.postMessage("Ahoy!", "*");
</script>
</html>
이는 http://jsbin.com/ahuzir/1 에서 작동합니다. 두 페이지가 동일한 출처 (jsbin.com)에서 호스팅되기 때문입니다. 그러나 두 번째 페이지를 다른 곳으로 이동하면 IE10에서 실패합니다.
이 답변을 처음 게시했을 때 착각했습니다. 실제로 IE10에서는 작동하지 않습니다. 분명히 사람들은 이것이 다른 이유로 유용하다는 것을 알았으므로 후손을 위해 남겨두고 있습니다. 아래의 원래 답변 :
주목할 가치가있는 것은 postMessage
IE8과 IE9의 별도 창에 대한 출처가 아닌 것으로 연결 된 해당 답변의 링크 이지만 IE10이 등장하기 전에 2009에서 작성되었습니다. 그래서 나는 그것이 IE10에서 수정되었다는 표시로 받아들이지 않을 것입니다.
그 postMessage
자체로 http://caniuse.com/#feat=x-doc-messaging 은 IE10에서 여전히 고장 났음을 나타내며, 이는 데모와 일치하는 것으로 보입니다. caniuse 페이지 는 관련성 높은 인용문이 포함 된 이 기사로 연결됩니다 .
Internet Explorer 8 이상은 부분적으로 문서 간 메시징을 지원합니다. 현재 iframe에서는 작동하지만 새 창에서는 작동하지 않습니다. 그러나 Internet Explorer 10은 MessageChannel을 지원합니다. Firefox는 현재 문서 간 메시징을 지원하지만 MessageChannel은 지원하지 않습니다.
따라서 가장 좋은 방법은 아마도 MessageChannel
기반 코드 경로 를 가지고 postMessage
존재하지 않는 경우 대체하는 것입니다. IE8 / IE9 지원은받지 못하지만 적어도 IE10에서는 작동합니다.
문서 MessageChannel
: http://msdn.microsoft.com/en-us/library/windows/apps/hh441303.aspx
실행기와 동일한 호스트에 프록시 페이지를 만듭니다. 프록시 페이지 iframe
에 원격 페이지로 설정된 소스가 있습니다. Cross-origin postMessage는 이제 IE10에서 다음과 같이 작동합니다.
- 원격 페이지는
window.parent.postMessage
데이터를 프록시 페이지로 전달하는 데 사용 합니다. iframe을 사용하므로 IE10에서 지원합니다. - 프록시 페이지는
window.opener.postMessage
데이터를 실행기 페이지로 다시 전달하는 데 사용 합니다. 이것은 동일한 도메인에 있기 때문에 교차 출처 문제가 없습니다. postMessage를 사용하지 않으려면 런처 페이지에서 전역 메소드를 직접 호출 할 수도 있습니다.window.opener.someMethod(data)
샘플 (모든 URL이 가상 임)
런처 페이지 http://example.com/launcher.htm
<!DOCTYPE html>
<html>
<head>
<title>Test launcher page</title>
<link rel="stylesheet" href="/css/style.css" />
</head>
<body>
<script>
function log(msg) {
if (!msg) return;
var logger = document.getElementById('logger');
logger.value += msg + '\r\n';
}
function toJson(obj) {
return JSON.stringify(obj, null, 2);
}
function openProxy() {
var url = 'proxy.htm';
window.open(url, 'wdwProxy', 'location=no');
log('Open proxy: ' + url);
}
window.addEventListener('message', function(e) {
log('Received message: ' + toJson(e.data));
}, false);
</script>
<button onclick="openProxy();">Open remote</button> <br/>
<textarea cols="150" rows="20" id="logger"></textarea>
</body>
</html>
프록시 페이지 http://example.com/proxy.htm
<!DOCTYPE html>
<html>
<head>
<title>Proxy page</title>
<link rel="stylesheet" href="/css/style.css" />
</head>
<body>
<script>
function toJson(obj) {
return JSON.stringify(obj, null, 2);
}
window.addEventListener('message', function(e) {
console.log('Received message: ' + toJson(e.data));
window.opener.postMessage(e.data, '*');
window.close(self);
}, false);
</script>
<iframe src="http://example.net/remote.htm" frameborder="0" height="300" width="500" marginheight="0" marginwidth="0" scrolling="auto"></iframe>
</body>
</html>
원격 페이지 http://example.net/remote.htm
<!DOCTYPE html>
<html>
<head>
<title>Remote page</title>
<link rel="stylesheet" href="/css/style.css" />
</head>
<body>
<script>
function remoteSubmit() {
var data = {
message: document.getElementById('msg').value
};
window.parent.postMessage(data, '*');
}
</script>
<h2>Remote page</h2>
<input type="text" id="msg" placeholder="Type a message" /><button onclick="remoteSubmit();">Close</button>
</body>
</html>
tangle에 의한 답변을 기반으로 다음 스 니펫을 사용하여 IE11 [및 에뮬레이트 된 IE10 모드]에서 성공했습니다.
var submitWindow = window.open("/", "processingWindow");
submitWindow.location.href = 'about:blank';
submitWindow.location.href = 'remotePage to comunicate with';
Then I was able to communicate using typical postMessage stack, I'm using one global static messenger in my scenario (alotough I don't suppose it's of any signifficance, I'm also attaching my messenger class)
var messagingProvider = {
_initialized: false,
_currentHandler: null,
_init: function () {
var self = this;
this._initialized = true;
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];
var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
eventer(messageEvent, function (e) {
var callback = self._currentHandler;
if (callback != null) {
var key = e.message ? "message" : "data";
var data = e[key];
callback(data);
}
}, false);
},
post: function (target, message) {
target.postMessage(message, '*');
},
setListener: function (callback) {
if (!this._initialized) {
this._init();
}
this._currentHandler = callback;
}
}
No matter how hard I tried, I wasn't able to make things work on IE9 and IE8
My config where it's working:
IE version: 11.0.10240.16590, Update versions: 11.0.25 (KB3100773)
Building upon the answers by LyphTEC and Akrikos, another work-around is to create an <iframe>
within a blank popup window, which avoids the need for a separate proxy page, since the blank popup has the same origin as its opener.
Launcher page at http://example.com/launcher.htm
<html>
<head>
<title>postMessage launcher</title>
<script>
function openWnd() {
var w = window.open("", "theWnd", "resizeable,status,width=400,height=300"),
i = w.document.createElement("iframe");
i.src = "http://example.net/remote.htm";
w.document.body.appendChild(i);
w.addEventListener("message", function (e) {
console.log("message from " + e.origin + ": " + e.data);
// Send a message back to the source
e.source.postMessage("reply", e.origin);
});
}
</script>
</head>
<body>
<h2>postMessage launcher</h2>
<p><a href="javascript:openWnd();">click me</a></p>
</body>
</html>
Remote page at http://example.net/remote.htm
<html>
<head>
<title>postMessage remote</title>
<script>
window.addEventListener("message", function (e) {
alert("message from " + e.origin + ": " + e.data);
});
// Send a message to the parent window every 5 seconds
setInterval(function () {
window.parent.postMessage("hello", "*");
}, 5000);
</script>
</head>
<body>
<h2>postMessage remote</h2>
</body>
</html>
I'm not sure how fragile this is, but it is working in IE 11 and Firefox 40.0.3.
Right now, (2014-09-02), Your best bet is to use a proxy frame as noted in the msdn blog post that details a workaround for this issue: https://blogs.msdn.microsoft.com/ieinternals/2009/09/15/html5-implementation-issues-in-ie8-and-later/
Here's the working example: http://www.debugtheweb.com/test/xdm/origin/
You need to set up a proxy frame on your page that has the same origin as the popup. Send information from the popup to the proxy frame using window.opener.frames[0]
. Then use postMessage from the proxy frame to the main page.
This solution involves adding the site to Internet Explore's Trusted Sites and not in the Local Intranet sites. I tested this solution in Windows 10/IE 11.0.10240.16384, Windows 10/Microsoft Edge 20.10240.16384.0 and Windows 7 SP1/IE 10.0.9200.17148. The page must not be included in the Intranet Zone.
So open Internet Explorer configuration (Tools > Internet Options > Security > Trusted Sites > Sites), and add the page, here I use * to match all the subdomains. Make sure the page isn't listed in the Local intranet sites (Tools > Internet Options > Security > Local Intranet > Sites > Advanced). Restart your browser and test again.
In Windows 10/Microsoft Edge you will find this configuration in Control Panel > Internet Options.
UPDATE
If this doesn't work you could try resetting all your settings in Tools > Internet Options > Advanced Settings > Reset Internet Explorer settings and then Reset: use it with caution! Then you will need to reboot your system. After that add the sites to the Trusted sites.
See in what zone your page is in File > Properties or using right click.
UPDATE
I am in a corporate intranet and sometimes it works and sometimes it doesn't (automatic configuration? I even started to blame the corporate proxy). In the end I used this solution https://stackoverflow.com/a/36630058/2692914.
MessageChannel doesn't work for IE 9-11 between windows/tabs since it relies on postMessage, which is still broken in this scenario. The "best" workaround is to call a function through window.opener (ie. window.opener.somefunction("somedata") ).
Workaround in more detail here
참고URL : https://stackoverflow.com/questions/16226924/is-cross-origin-postmessage-broken-in-ie10
'program tip' 카테고리의 다른 글
쉬운 디버깅을 위해 Rails에서 객체의 내용을 어떻게 인쇄합니까? (0) | 2020.09.09 |
---|---|
기억과 관련하여 경기장이라는 용어의 의미는 무엇입니까? (0) | 2020.09.08 |
명령 줄을 사용하여 JUnit 클래스에서 단일 테스트 실행 (0) | 2020.09.08 |
이러한 유니 코드 결합 문자는 무엇이며 어떻게 필터링 할 수 있습니까? (0) | 2020.09.08 |
ReSharper Curiosity : "매개 변수는 전제 조건 확인에만 사용됩니다." (0) | 2020.09.08 |