What Happened to Operation Aborted?
Have you ever seen this dialog while surfing the web in Internet Explorer?
You browse to your favorite news site. The content starts loading, you've already started reading the headline, and then it happens. Those of you familiar with the operation aborted dialog know that it spells sudden doom for the website you're currently viewing. Unsuspecting users have no idea what it means and simply click 'OK' and then watch in horror as the web page they were just reading disappears; only to be replaced by an navigation error screen. More savvy users move the dialog out of the way so that they can finish reading what was visible before they too accept the inevitable...
This dialog (and its side-effects) is gone in Internet Explorer 8 Beta 1.
What caused the operation aborted error?
The operation aborted dialog in Internet Explorer 7 is triggered by an HTML parsing exception that occurs when all the following specific conditions are met:
- The HTML file is being parsed
- Script is executing
- The executing script attempts to add, or remove an element from an unclosed ancestor in the markup tree (not including the script block's immediate parent element).
You can see that each of these conditions is true in the following example markup:
<html> <body> <div> <script type="text/javascript"> var newElem = document.createElement('foo'); document.body.appendChild(newElem); </script> </div> </body> </html>
The HTML file is being parsed, and encounters a script block. The script block contains inline script which creates a new element and attempts to add it to the BODY (document.body.appendChild(newElem)
) element before the closing BODY tag has been encountered by the parser. Note that if I removed the highlighted DIV element, then this problem would not occur because the script block's immediate parent would be BODY, and the script block's immediate parent is immune to this problem.
Unfortunately the operation aborted dialog was always thrown at the top-level of a web page, even if the problem occured in an iframe. In fact, in most scenarios that we encountered, ad injection in an iframe was usually the root cause of this error. After the user dismissed the error dialog, Internet Explorer would navigate away from the page.
What we did in Internet Explorer 8 Beta 1
In Internet Explorer 8, our goal is to change the behavior that previously caused the following problems:
- The operation aborted error was a modal dialog. The dialog was not actionable by any user.
- Dismissing the operation aborted dialog caused Internet Explorer to navigate to an error page. This prevented any potential debugging of the affected page.
When the HTML parser throws the operation aborted exception, rather than announce this error to the world, Internet Explorer 8 Beta 1 discreetly tucks this information away into the list of script errors associated with the webpage and stops parsing HTML and running script at that point. We also tried to provide a little more help to those developers who encounter this error (but don't read the IE blog) by including the KB article number in the text that describes this problem:
HTML Parsing Error: Unable to modify the parent container element before the child element is closed (KB927917)
A simple web search for "KB927917" in major search engines will usually turn up the corresponding Knowledge Base article as the first hit. That article describes the specifics of this problem and available workarounds.
Interoperability observations and feedback request
It's intriguing to observe the parsing behavior of various browsers in these situations, as it's not universally consistent. For the scenarios involving adding elements to an open container (e.g., appendChild), the appropriate behavior seems very straightforward--just add the element. Future markup encountered by the HTML parser (after execution of the script block) should then be appended to the existing in-memory DOM. Other browsers tend to agree on this point.
In the case where a parent element is removed (e.g., removeChild, innerHTML, outerHTML) and parsing resumes, the big question becomes: what is the parser's new context? Different browsers answer this question differently. By and large, most other browsers invalidate the parsed context from the point of deletion in the DOM, and "remember" what was deleted such that future parsed markup is ignored until the containing tree (now deleted in-memory) is closed. You can start to see the complexity in this approach, especially if the tree is not well-formed. On the other hand, other browsers take a different approach and "re-base" the parsing context of the current markup at the point of deletion. This results in future markup being inserted in "the wrong place" (a matter of perspective) in the in-memory DOM. For illustration purposes, consider the former as "approach A" and the latter as "approach B." Given the following markup, what do you as web developers expect? I tend to think that approach A is the saner model to follow:
<html> <body> <div id="container1"> <div> <span id="span1">First block of text</span> <script type="text/javascript"> document.body.removeChild(document.getElementById('container1')); </script> <span id="span2">Second block of text</span> </div> </div> <div id="container2"></div> </body> </html>
Final DOM tree constructed using each approach mentioned above:
Approach A |
Approach B |
html |-body |-div#container2 |
html |-body |-span#span2 |-div#container2 |
What can you do?
In any case, the moral of the story is to avoid getting yourself into this scenario if possible. Granted, in some cases it may be inevitable, especially if the content is not under your direct control (like ad-injection scenarios). Knowledge Base article 927917 mentions some workarounds, but additionally to avoid the problem, you simply need to ensure that your script doesn't meet all three of the conditions I outlined earlier. So, if possible, do the following to avoid an operation aborted error:
- Moving your script execution to a function that is invoked after parsing is complete (e.g., onload)
- Adding the defer boolean attribute to the script block (this defers execution of the script content until parsing is complete)
- Limiting your tree modifications to the script-element's immediate parent
- Moving the location of your script block to a child of the body (this usually solves most problems, while allowing the most flexibility in terms of scenarios).
Always a pleasure,
Travis Leithead
Program Manager
IE8 Object Model
Comments
Anonymous
April 23, 2008
The comment has been removedAnonymous
April 23, 2008
The comment has been removedAnonymous
April 23, 2008
There is nothing worse in a program than excessive modal dialogs. I cringe every time I use a program that shows more than one in a row. This is the kind of development strategy that may make IE once again a leading browser. I want see as much competition as possible. Down with modals!Anonymous
April 23, 2008
This is why I use Firefox. IE just nags and fails to display the content properly on some websites I go to. Also the things I'm use to in Firefox don't work on IE (i.e being able to Google (not MSN search) when I type CTRL->K (usually I type CTRL-T CTRL-K to get a new tab and put the cursor at the top for a Google search).Anonymous
April 23, 2008
The comment has been removedAnonymous
April 23, 2008
The comment has been removedAnonymous
April 23, 2008
Aah, forgot something: How will the proposed workarounds/solutions affect behavior in other browsers? (I. e. will those be an IE-only fix, then?)Anonymous
April 23, 2008
The comment has been removedAnonymous
April 23, 2008
<p onclick="innerHTML='<CENTER></CENTER>'"><button>click here</button></p> <iframe src="javascript:'<script>top.ff1={abc:function(){}}</script>'" width=0 height=0 name="f1"></iframe> <button onclick="f1.location='about:blank';setTimeout('alert(ff1.abc())',0)">click here</button> <iframe src="javascript:'<script>top.ff2={abc:function(){}}</script>'" width=0 height=0 name="f2"></iframe> <button onclick="f2.location='about:blank';setTimeout('alert(ff2.toString())',0)">click here</button>Anonymous
April 23, 2008
Some of you act like this behaviour was the end of the world... ZiggyFish, have you used IE at all? Why doesn't CTRL-E and CTRL-T work for you after setting Google to the default search provider? If things like this makes you use another browser I don't know what to say...Anonymous
April 23, 2008
That's what I call a move into a right direction. Keep the complicated things out of the common user's interface and let the page render even if browser thinks it's broken.Anonymous
April 23, 2008
The comment has been removedAnonymous
April 23, 2008
The comment has been removedAnonymous
April 23, 2008
The comment has been removedAnonymous
April 23, 2008
I have never ever seen this error message and I'm a developer.Anonymous
April 23, 2008
Trident still has problems, but I can see that it's going to take a while to get it up to speed. Afterall, you can't make a brand new rendering engine in just six months.Anonymous
April 23, 2008
Wouldn't it better to fix the actual bug? This works fine in Safari, Opera and Firefox.Anonymous
April 23, 2008
For what it's worth, the HTML5 spec defines precise rules for handling all these edge cases, so once browsers implement them, these issues will all go away.Anonymous
April 23, 2008
Why is there a restriction on appending new nodes to unclosed elements (other than the parent of the script)? Wouldn't it be better to actually fix your broken DOM implementation, instead of just covering up errors like this. FWIW, the HTML5 spec actually handles all of these cases sanely. Maybe you could take a look at that for a real solution.Anonymous
April 23, 2008
> A simple web search for "KB927917" There is no such thing as a simple search for a database ID.Anonymous
April 23, 2008
I agree with George "This was one of those... "OMG! I can't believe they shipped IE7 with this not fixed!" things. " and also with DD. The "better" error messaging in the IE8 beta may (temporarily) help BUT this is a browser bug that should be FIXED, also in IE6 and IE7. By the way, I pointed this problem, as well as the root cause (unclosed div), out in response to a previous blog as well as in the IE newsgroup but got no response - neither from Microsoft nor from an MVP.Anonymous
April 24, 2008
The comment has been removedAnonymous
April 24, 2008
I remember getting this on bloated large media comporation sites and on Neowin.net. Most of the times after clicking OK, I quickly pressed Esc so IE didn't navigate to the error page and whatever part was loaded was still readable. Thank you for making it go away. IE8 is turning up to be much better than IE7 and a must-have upgrade but still the IE team has a very long way to go before claiming standards compliance (cough) XHTML, XML (and various standards like XForms, MathML, XPath 2.0 etc), DOM 2, DOM3, CSS3, SVG, ECMAScript extensions 1.5/1.6/1.7/1.8 and future technologies, HTML 5 and ECMAScript 4.Anonymous
April 24, 2008
I've not encountered this before. Happens to dubious websites with lots of ads?Anonymous
April 24, 2008
The comment has been removedAnonymous
April 24, 2008
The comment has been removedAnonymous
April 24, 2008
This happens very often with the new version of GMail. Also some airline sites have this problem. It's a big AJAX pain. Glad to see the behaviour will improve.Anonymous
April 24, 2008
Btw, this page (http://arstechnica.com/journals/microsoft.ars/2008/04/22/microsoft-releases-two-more-ultimate-extras) is excellent for perfecting IE8's image scaling algorithm.Anonymous
April 24, 2008
Tino: There is no one place to point to really, it's just fundamental to the way the parser algorithm is written. Basically the DOM tree is almost never examined by the parser, instead the parser keeps and uses a separate set of state that is unaffected by changes to the DOM. For example, appends almost always happen to elements in the "stack of open elements" rather than to elements in the DOM. (Off-hand the only exception I can think of is for the handling of misnested formatting tags, which have a complicated algorithm that does dive into the DOM, but again the way the algorithm is designed it should work regardless of what a script has done to the DOM.) HTH.Anonymous
April 24, 2008
Ian: yes, that helps and confirms what I already thought would be the case. It is a bit confusing though that the spec covers document.write() and .innerHTML in detail but fails to mention normal DOM manipulation in the same section...Anonymous
April 24, 2008
The comment has been removedAnonymous
April 24, 2008
The comment has been removedAnonymous
April 24, 2008
The comment has been removedAnonymous
April 24, 2008
Heh... it's baaack, and hits on this page... http://www.dilbert.com/strips/ ...even if active content is refused. Back navigation from the can't-load page gets the wanted page back, which is good. Tested with IE8b1 over IE7 RTM on XP SP2, Standards Mode, set to prompt on active content. In this particular test, all such prompts were cancelled (i.e. active content was refused), which suggests a different mechanism? I'll try for repro, and log as a "bad page" if I succeed.Anonymous
April 24, 2008
The comment has been removedAnonymous
April 25, 2008
The comment has been removedAnonymous
April 25, 2008
The comment has been removedAnonymous
April 25, 2008
You all have little to whine about.Anonymous
April 25, 2008
How about an end-to/redesign of those pesky dialogue boxes (including vista ones) all together e.g. http://blog.mozilla.com/faaborg/2007/03/06/would-you-like-to-redesign-notification-in-firefox-yes.-not-now.-never./Anonymous
April 26, 2008
The comment has been removedAnonymous
April 26, 2008
Travis (author of this article) ... are you going to respond to the comments ?Anonymous
April 26, 2008
The general consensus seems to be that you should not be generating a script error, but instead should queue the request until the appropriate tag is closed. It works for the other browsers. Is this such a problem for IE to do also? Plus, don't just fix it in IE8. We want it retro-fitted to IE6/7 also.Anonymous
April 27, 2008
Know what would be really great? If Microsoft, *nix vendors, and Apple got together and made it so I wouldn't have to patch my site's FONT-SIZE! Seriously load my site in XP, then bring it up in Ubuntu....then go over to a Mac. You'll see it looks fine in XP because that is what I work with by default and it's how I prefer things to look any way. I'm not a fonts expert but the inconsistency is beyond stupid. Please ... someone get people talking about this issue; it's beyond sad right now that I can expect my CSS dimensions to work cross platform while havnig to seriously consider serving a second style sheet JUST to fix font-sizes for entire platforms!Anonymous
April 27, 2008
@JAB 3: oooh, font rendering...
- fact 1: installed fonts are not the same from one OS to the other, so you can't have the same rendering on all platforms; you can however select fonts with similar metrics and face (Helvetica, Arial and DejaVu, or Liberation Sans, for example, are very close)
- fact 2: IE can't deal with font metrics, and interpretes font size in a non-standard way
- fact 3: glyph rendering priorities change from one platform to the other: MS tries to match to pixel grid, Apple matches to best paper representation, Linux... depends on user settings (:P) Solution: wait for CSS3 support and @font-face.
Anonymous
April 28, 2008
@DD, Authors almost never respond to comments made on this blog.Anonymous
April 28, 2008
Is it really gone in the version that everybody can download, or in a newer build? Also, does this also apply when IE is running in IE 7 compatiblity mode? Why I ask? This is why: http://i30.tinypic.com/35i1unq.jpgAnonymous
April 28, 2008
When will Beta 2 be available? Beta 1's been out for a while now.Anonymous
April 29, 2008
This post takes about a day and a half to load. Please lead by example: 1.) Crop your screenshots so that only the important parts are shown 2.) Use PNG Crush to shrink your PNG images 3.) Use GZip or similar for your files 4.) Add a proper expires header to your static content (the screenshots, CSS, JS) so that every visit to this blogs homepage, doesn't require me to download 300k of images that I already have in my cache.Anonymous
April 29, 2008
What is really sad is that the screenshots were taken as JPEGs (look at the lossy pixelation), then converted to PNGs because that is a better format for screenshots. What was missed is that PNGs are better, but if you convert from a lossy JPEG its too late! You've already messed up the image. I just tried a CRUSH on the first PNG... saved 42k in image size! I thought it was just this site that was slow, but I think the caching thing is what is messing it up.Anonymous
April 29, 2008
Oh, very cool, Microsoft friends read my http://motls.blogspot.com/ where this error frequently occurs and people frequently complain to me. Could someone please figure out what is the reason and maybe even how the scripts should be modified to avoid the problem? A nice person can submit any comment under any article in my blog. Also, I wonder that Firefox seems to solve it OK without creating a new scientific discipline about it. ;-)Anonymous
April 29, 2008
@Lenen - that is disappointing. I wonder why they offer a comments section if they don't plan to have a dialog on the subject. So basically it's a case of: "This is what we're doing, you might all be developers with an equally valid point of view as us at MS, so have fun writing your comments, but this is what we're doing so get used to it."Anonymous
April 30, 2008
Haha, you haven't figured it out yet? Large corporations generally run blogs for marketing reasons, not to increase geniune communication with their customers.Anonymous
April 30, 2008
Wrong post to put this question under, but: I haven't had a chance yet to check out IE8, but I just wanted to ask, are you guys going to allow prototyping in JavaScript in this version, much like Mozilla and Opera allowed?Anonymous
April 30, 2008
@Dmitri: The entire Javascript language is based around prototypes, thus IE has supported prototypes in JS for a very very long time. What precisely are you trying to do that isn't working in IE?Anonymous
April 30, 2008
The comment has been removedAnonymous
April 30, 2008
@Harold-- Didn't Mozilla pull out array prototyping because it allows data theft from JSON? http://ejohn.org/blog/re-securing-json/Anonymous
April 30, 2008
Oh, and if you'd like to vote for Prototyping to be fixed in IE8, here's the link to the IE8 Bug Tracker for bug #333956 https://connect.microsoft.com/IE/feedback/ViewFeedback.aspx?FeedbackID=333956Anonymous
May 01, 2008
The comment has been removedAnonymous
May 01, 2008
The comment has been removedAnonymous
May 01, 2008
@Dave: Actually, the WebKit blog is very good about communicating with developers who post there (http://webkit.org/blog) and also has much more interesting posts. Take a look if you want to see the right way to manage a developer blog (you'll also get a nice window into the future of the web).Anonymous
May 02, 2008
The comment has been removedAnonymous
May 02, 2008
@REX: Use the DEFER attribute on your script. Beyond avoiding this browser limitation (on ie8 AND older versions) it will improve the performance of your page.Anonymous
May 02, 2008
@Bill Thats not the point. I shouldn't have to use a proprietary non-standard attribute to solve an IE bug. More importantly, if I have another script elsewhere on the page, that LEGITIMATELY tries to interact with the elements I created/altered, BEFORE the DEFER'd script is executed, then I'm STILL going to have ERRORS. Please fix this bug, properly.Anonymous
May 02, 2008
Rex: http://www.w3.org/TR/html401/interact/scripts.html#h-18.2.1 You might as well look before speaking up. From what I see the defer attribute seems to be defined in the HTML Spec. Whatever you call proprietary, I don't think this is. As for UX and bug fixing: Right, the bug remains. You may assume that different people work on the UX and the parser, so jumping into the UX people's face for a bug they can't and won't fix is futile. And please remember that there are many more users than web designers/developers who will actually benefit from a better user experience. Most pages that throw this errors probably render fine and just lack ads ... who cares, really? And you may have noticed that there are two distinct ways of dealing with that problem, outlined in the post. Both yield different results in the final DOM tree and (a) no spec is given what method to use, (b) the other user agents seem to have a hard time doing all the same. Granted, IE introduces a third behaviour here, but in any event triggering this case will yield headaches for web developers as the final DOM tree will be different from browser to browser – and this is not exactly an IE problem. You lose nothing from moving the script evaluation after parsing and before rendering and will gain consistent behaviour. From what I see, you call for a solution to a non-problem. (Hint: CSS bugs are harder to work around so I'd rather see those fixed than this :))Anonymous
May 03, 2008
3 words for this "fix". T-O-T-A-L C-L-U-S-T-E-R F-U-D-G-E Just fix the bug, don't give us these IE-Only workaround band-aid On-Error-Resume-Next kind of amateur software development cruft. T-O-T-A-L C-L-U-S-T-E-R F-U-D-G-EAnonymous
May 03, 2008
The comment has been removedAnonymous
May 03, 2008
The comment has been removedAnonymous
May 05, 2008
The comment has been removedAnonymous
May 05, 2008
Hi, know this is off topic, but I'm missing the transcript from the April chat.. In the March transcript you wanted use cases for adding support for CSS 3 stuff: Please add :nth-child(), this doesn't just affect CSS but also JavaScript since you have decided to add querySelector[All] support. Every major JS Library out there support some kind of getElementByCSS (aka $$ ) to get elements, and they have some kind of :nth-child() support (though some of them call it :child(), :odd and :even). Adding :nth-child would help them (and me) accelerating those functions by using querySelectorAll if supported in most common cases (yes, :child, :odd and :even are commonly used by users of todays JS libraries / framworks). Also, by the time ie8 is out all other major browsers will support querySelectorAll and :nth-child (Safari already does). Other then that: Please force every ie < 8 user to update to ie8 when it is stable ;)Anonymous
May 06, 2008
The comment has been removedAnonymous
May 06, 2008
The comment has been removedAnonymous
May 06, 2008
Please don't be juvenile about this, Andrew. Sarcasm is the lowest form of wit and it's off topic anyway. I do tend to agree that there are annoying discrepancies between the IE VM and the JS standards. I also agree completely that it is not acceptable to have to alter content based upon the requesting browser. However that's not what I'm talking about here. I am really fired up about that fact that some folks on this forum seem to want a situation where they do not have to prepare adequately for exceptions and then get to blame the vendor for their own lack of diligence at design time. What's next - blaming Microsoft because your divide by zero causes a crash? Perhaps you'd like them to remove that dialog too?Anonymous
May 06, 2008
well done Greg. finally some common sense. you'll never change their blinkered zealotry thoAnonymous
May 06, 2008
Cheers Frank. I think 'blinkered zealotry' is a bit harsh, though. These guys are just looking for a solution and it is frustrating for all of us when the platform causes issues. But I guess I just want an acknowledgement in this particular case that the answer to the problem is 'anticipate and handle a concurrency error in my scripts' rather than 'ask Microsoft to ignore my concurrency error'. Inserting nodes into an unparsed or partially incomplete DOM is, after all, playing off the board and tempts problems. In that case, it would be foolish not to try and design the script better, rather than pointing fingers in all the wrong places.Anonymous
August 12, 2008
[ASP.NET AJAX] Accesso sicuro al DOMAnonymous
September 09, 2008
Here's another tricky JavaScript error that could leave you bewildered and frustrated... Internet ExplorerAnonymous
November 27, 2008
The comment has been removed