IE - access is denied
loxy opened this issue · 11 comments
Hi,
I get an access denied error in an angular application on Internet Explorer 11, chrome works fine. The docs say:
Unfortunately, IE blocks direct post messaging between a parent window and a popup, on different domains.
But we are not using popups (I think you mean window.open(...), right?). So, is it always necessary to use the suggested "bridge system" when running on IE?
Hi @loxy,
Yeah, if you're just using iframes, you should be fine -- you should not need the bridge.
Can you let me know:
- A quick example of your post-robot code?
- Can you make sure IE is not running in any kind of compatibility mode?
- Is there any chance IE is running in intranet mode? You can run the following function to find out:
(function() {
window.status = 'testIntranetMode';
console.log('intranet mode:', window.status === 'testIntranetMode');
})();It seems so that we are running in intranet mode. Your function returned true.
We are not running any compatibility mode:
<meta http-equiv="X-UA-Compatible" content="IE=EDGE" />
We are running a portal app which includes several apps in an iframe, always one at a time. Now we want to synchronize the URL of the portal with each app and vice versa. One can say the URL is divided into two parts: portal part and app part.
So when we load a new iframe (an app) we emit a TRY_TO_NAVIGATE event to the app with the proper app part URL. If the location changed somehow the iframe is not loaded again, if it is a link to the same app. This is of course not true for a link to an unloaded app.
It all works great on first load and when switching between the same app. Even for the second app loaded. But as soon as a third app comes into play (even if it was the first loaded app) it breaks. To illustrate:
Apps: A, B, C
States in App A: A_1, A_2, ... (same goes for other apps)
A_1 -> A_2: works
A_1 -> B_2 -> B1: works
A_1 -> B2_ ->A1: broken
A_1 -> B2_ ->C1: broken
The call to post robot look like this:
onApplicationLoad(contentWindow: Window) {
console.debug(`[AppHolderController] - ${this.src} completely loaded`);
this.currentWindowService.currentWindow = contentWindow;
robot
.send(contentWindow, NavigationCommand.TRY_TO_NAVIGATE, {url: '/' + this.$stateParams.tail})
.catch(function (err) {
console.error(`[AppHolderController] - ${NavigationCommand.TRY_TO_NAVIGATE} failed:`, err);
});
}
The function is called when the load event of the iframe is fired...
Is the intranet mode problematic? Never heard of it before. Fucking IE...
Intranet mode has been problematic in weird and interesting ways, yes. If I can try to repro the exact scenario I can see how fixable it is though.
Question -- are these frames and the parent page all on the same domain, or multiple different domains?
At least different ports, but it should work on different domains too. I can provide a sample repo, but it is written in typescript, compiled through webpack.
Ok, i tried to create a minimal sample repo. Here is the link: https://github.com/loxy/ie-intranet-bug
If you have questins feel free to contact me...
Ups, I had a bug in the compilation process. Now it should work. But tried the app at home in a non intranet IE11. Same problem, so it has nothing to do with this mode...
Hmm strange -- sorry for the delays in trying this, got a lot on my plate atm but I'll try to get to it soon.
Any updates on this?
OK, I cloned your repo, repro'd the issue, and added a fix. I'm no longer seeing errors from post-robot -- can you try installing the latest (7.0.12) and let me know if you still see the issue?
If you're interested, the issue I found was this: (recording for my own sanity next time something like this happens)
post-robotrelies pretty heavily onWeakMapto keep references to windows without leaking memory for closed windows- We wrote our own polyfill for
WeakMapfor older browsers: https://github.com/krakenjs/cross-domain-safe-weakmap -- since none of the existing polyfills seem to take into account that theWeakMapkey might be a cross-domain window object, which will error out when you try to attach any properties to it. - In order to find if a window is a valid key for a given
WeakMapinstance, we do something likeif (keys.indexOf(win) !== -1) - Even though
indexOfshould just be doing strict equality checks inindexOf, it turns out that if one of the windows in thekeysarray is closed or destroyed in a particular way, some weird stuff happens:keys[i]gives undefined, even though there was originally a window object at that index (woot, references being changed transparently!).keys.indexOf(something)always throws aPermission deniederror. I'm wondering if IE is doing something weird like trying to dig into the properties of the object and erroring out, rather than just sticking to a strict equality check? And of course, this permission denied error has no stack trace to speak of...- Incidentally, this seems to explain why the issue for you only happened after some windows/frames have been opened/closed
cross-domain-safe-weakmapwas doing a cleanup run overkeysforset,deleteetc. to check for closed windows, but not forgetsince this is normally more of a hot path.- Fix for now was to do that cleanup run even for
get, since it's a slow path anyway (normallycross-domain-safe-weakmapwill rely on nativeWeakMapif it's available)
TLDR: IE is an awful, awful browser. But we knew that anyway right?
Sorry again for the delay in getting to this. Appreciate the thorough example, it really helped!
Great! It's working now. Thank you for the detailed explanation!
And yes, we all love it...
@Mischi: It's time to switch, right?
Sweet!