Bug 137817

Summary: XMLHttpRequest(s) aborted when they should not be
Product: WebKit Reporter: Mirko Tschäni <mirko.tschaeni>
Component: WebCore JavaScriptAssignee: Nobody <webkit-unassigned>
Status: REOPENED ---    
Severity: Critical CC: ap
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: All   
OS: All   
Attachments:
Description Flags
Isolated reproduction of the issue
none
test application none

Description Mirko Tschäni 2014-10-17 06:42:38 PDT
Created attachment 240013 [details]
Isolated reproduction of the issue

Pending	XMLHttpRequests	get aborted by the browser as soon as document.location.href is	assigned a new value.In some cases this is wrong. For instance if the response has a content type that can not be rendered in the browser window, the browser will show a "save as" dialog to the user and continue showing the old page. The same	is true	for responses with a content-disposition: attachement header. After the response has reached the browser, and the save as dialog has been shown to the user, the page will work like normal again.

This causes unexpected behaviour is the	current	page, as it will be temporarily	unable to issue	ajax request, even if the page is not actually	unloading.

Correct	behaviour would	be: Wait with aborting pending ajax request until the response reaches the browser and consists	of browser renderable content. If the response will not be rendered in the browser window (non renderable content-type, content-disposition: attachment), then the browser should unload the page (and abort pending ajax requests).

In webkit also all new ajax requests that are started in the time between document.location.href assignment and arrival of the download will be aborted immediately. Firefox for instance is also affected from this bug but only for pending requests, new ajax requests will work as expected.


Affected Browsers: safari, webkit, firefox, chrome < 37
Not affected Browsers: Internet	Explorer, chrome 37+
Comment 1 Alexey Proskuryakov 2014-10-18 23:27:35 PDT
Yes.

*** This bug has been marked as a duplicate of bug 23933 ***
Comment 2 Mirko Tschäni 2014-10-21 08:49:05 PDT
I agree that this issue is a duplicate of https://bugs.webkit.org/show_bug.cgi?id=23933 technically. 
However there are two reasons why i thing resolving this as a duplicate is not ok.

1. The summary of bug 23933 suggests that the issue is only related to form submits when actually the issue affects any kind of navigation (to downloads but also browser renderable contents)

2. In the comments of bug23933 Alexey Proskuryakov suggests that download related issues should not be discussed in a bug that was filed about submitting forms.


Depending on the application i think this issue is close to impossible to work around. 

Imagine the following situation:

A site uses a third party java script that implements a embedded chat. As soon as the user clicks any link or submits a form that has a target of self, starting with the click until the response arrives, the third party chat will be unable to send any ajax request. Even worse, is is not event possible to detect this situation and the chat is unable to know whether this is some major issue (like a network outage) or just the user navigating to some other url. Especially if the server takes a while to respond (which is often the case for uploads, that's why this bug was first discovered there).
WebKit should wait with aborting ajax requests until the response has arrived, because only then webKit can decide whether the browsing context is to be unloaded or not.

If the response is browser renderable: do not abort
If the response is not browser renderable (by content type or because the response has a content-disposition: attachment header).

Please: either change the title of bug23933 and re priorise or do not mark this bug as a duplicate of 23933.

By the way: this issue has been fixed in the most recent versions of chrome/blink (chrome 36+)
Comment 3 Mirko Tschäni 2014-11-14 05:40:35 PST
Created attachment 241582 [details]
test application

An improved and more detaild test application that tests request aborts (ajax, image and websocket) in different situation. The test application is also available online here: http://lab-browserillegalrequestabort-1.unblu.com/.
Comment 4 Mirko Tschäni 2014-11-14 05:47:51 PST
I have implemented a better test application that tests in detail, which requests are aborted and when. Using this test application (available as an attachment as well as online at http://lab-browserillegalrequestabort-1.unblu.com/) I have testet a selection of major browsers (Chrome, Internet Explorer, Firefox and Safari as well as other webkit based browsers) in the most recent versions as well as some older versions (i.e. Safari 6, Firefox 24).

The test application covers a wide range of variations and the results relevant for Safari are consistent across all variations and tested versions.

The application tests with different kinds of requests (XMLHttpRequest, image and WebSocket)
The application tests whether requests are aborted during step 12 of https://html.spec.whatwg.org/multipage/browsers.html#navigating-across-documents 
The application tests during different phases of the document life cycle (loading, loaded)
The application tests using same origin resources as well as x-origin resources


Safari aborts all pending request (except WebSockets) in all variations as soon as a new value is assigned to the document location.

The majority of browsers (Chrome and InternetExplorer) DO NOT abort any requests in the same scenario.

Firefox does also abort requests just like webkit while webkit also aborts websockets.

In addition to aborting requests on location assignment, safari also does not allow the creation of new requests after the assignment. If the response turns out to be a download or other content that is not renderable in the browser, safari re allows the creation of new requests.

All other tested browsers (Firefox, Chrome and Internet Explorer) do always allow the creation of new requests, also in the time between a location assignment and the eventual unloading or hand  off to external application or download depending on content-type and content-disposition.

Please also read trough: http://lab-browserillegalrequestabort-1.unblu.com/info.html (description of the test application).
Please note that the same issue has also been reported with mozilla under https://bugzilla.mozilla.org/show_bug.cgi?id=1084399
Comment 5 Mirko Tschäni 2014-11-17 07:22:22 PST
I have filed a spec issue here: https://www.w3.org/Bugs/Public/show_bug.cgi?id=27347.
Comment 6 Mirko Tschäni 2014-12-01 05:21:00 PST
The related spec issue (https://www.w3.org/Bugs/Public/show_bug.cgi?id=27347) has been updated with additional tests.

Now the test suite also tests whether a navigation inside a nested browsing context (iframe) is aborted when the parent browsing contexts starts a navigation.

Now the test suite can also run the tests cases inside an iframe, to test whether the navigation on the parent browsing context will have the same effect on the requests (ajax, image, iframe and websocket) inside a nested browsing context.