Problem/Motivation
Internet Explorer is supposed to be a HTTP-based HTML browser. There are a lot of examples where neither HTTP nor HTML is implemented properly.
One example is the concept of Content-Type headers. If you specify application/json as such header, then IE 9
starts to download the response. This Content-Type is set by AjaxResponse by default, so file uploads for example don't work in IE.
Random observation:
Default accept header
image/jpeg, application/x-ms-application, image/gif, application/xaml+xml, image/pjpeg, application/x-ms-xbap, application/x-shockwave-flash, application/msword, */*
Steps to reproduce:
- Using Internet Explorer 11 on Windows 7
- Install Drupal 8.0.x using the Standard profile
- Open Internet Explorer 11
- Browse to
node/add/article
- Press F12 to open the IE Developer Tools
- Find the Document Mode pull-down menu at the upper-righthand corner of the Developer tools, and select '9'
- In the 'Add Article' Image field, click Browse to add an image
- select a sample image file from the Upload dialog and click open
- Behavior in IE9 emulation is a continuously spinning-blue process wheel next to the Upload botton, and no preview image appears.
- Behavior in IE10, IE11, and Chrome is preview image that appears below the Image and fields.
Proposed resolution
Figure out the best solution.
Remaining tasks
User interface changes
API changes
Beta phase evaluation
Comments
Comment #1
wim leersROFL :D
Comment #2
dawehnerLet's try this "solution"
Comment #3
dawehnerLet's try this "solution"
Comment #4
dawehnerLet's try this "solution"
Comment #5
dawehnerLet's try this "solution"
Comment #6
dawehnerLet's try this "solution"
Comment #7
Crell commentedComment #9
webflo commentedComment #10
webflo commentedSorry added this line accidentally.
Comment #11
dawehnerI wonder whether we can come up with some basic integration test, to ensure that we get the proper header?
Sad story ...
It would be great to add an TODO to improve this strpos once #2331919: Implement StackNegotiation is in.
Comment #12
webflo commentedAjaxResponse has to handle two diffrent request headers.
jQuery Form falls back to submit via a hidden iFrame in Browser which does not support File Uploads via XHR Requests. More documentation about this is on http://malsup.com/jquery/form/#file-upload.
Maybe we should explicit check for HTTP_X_REQUESTED_WITH as described in this example?
Comment #13
webflo commentedBump to critical because IE 9 is a fully supported browser.
Comment #14
seanAtUSDA commentedIn my custom applications, I have run into the same issue with IE. I resorted to using a content-type of text/plain for all of my JSON responses.
Comment #15
dawehner@seanAtUSDA
Would you mind manually testing this manually in various IE variants? This would be really great!
Comment #16
wim leersYAY! CONSISTENCY!
Comment #17
wim leersAlready added some, but could use more :)
Comment #18
dawehner.
Comment #19
dawehnerComment #20
catchAccording to http://www.netmarketshare.com/browser-market-share.aspx?qprid=2&qpcustomd=0 IE9 usage is down to 9%. I'd personally be OK with treating IE9 bugs as 'major' - we'd still fix issues if they come up as opposed to won't fix, but not hold up release on it.
For administering Drupal sites, you should be able to use the latest version of a major browser. If you're not allowed to use the latest version of a supported browser to do that, you're probably not going to be allowed to use Drupal 8 anyway.
For site visitors it's up to the site builder to decide which browsers they support and which features are exposed to end users. Some sites work fine without users triggering ajax responses, some won't.
Comment #21
Crell commentedIf this bug is in IE9, does it mean it's also in IE 8? I know we have already told IE 8 to get stuffed, but it has a disturbingly large presence on that pie chart...
I don't recall the last time I used IE period, much less an old version of it, so I wouldn't mind downgrading to major here.
Comment #22
dawehnerAccording to various stackoverflow entries, this seems indeed to be the case as well for IE 8.
Comment #23
catchIE8 doesn't get any JavaScript at all, so there's no AJAX request to fail.
Comment #24
dawehnerEven I don't care about the IE9 users so much, I do care about the site builders
which would have to fix that for some of their users. Figuring out what is going on here,
is extremly frustrating, its far from being obvious.
Given that I would argue we should make a general policy how much we would support IE9, make some decision there,
but get this issue in, given that we save time for us, the community.
Does anyone has an oppinion?
Comment #25
catch#2390621: [policy, no patch] Update Drupal's browser support policy.
Comment #26
xjmComment #27
xjmDiscussed with @catch, @alexpott, @webchick, @Dries, and @effulgentsia. For now, IE9 is a supported browser, and this is actually a significant bug that site builders and users can't reasonably work around if they can't simply use a different browser (which is common for IE users). If we decide in #2390621: [policy, no patch] Update Drupal's browser support policy to change our IE9 support we will downgrade this.
Comment #28
ericjenkins commentedI am at a Sprint right now. I am following: https://www.drupal.org/contributor-tasks/add-steps-to-reproduce
I have added "Needs steps to reproduce" tag to this issue. I will remove this tag if I can reproduce the steps and document it.
Comment #29
ericjenkins commentedSuccessfully reproduced the image upload quirk using IE9 emulation in IE11. Added a Steps to reproduce section to the Issue Summary and documented the steps to reproduce there. Removed the tag: Needs steps to reproduce.
Comment #30
dawehnerDo we maybe want to check first whether the request format is iframeupload?
Comment #31
corbacho commentedI've spent some time researching about this bug and testing
This is how the problem looks in Windows 7 - IE9 not emulated:
As webflo said, this bug is present only in forms with file uploads, in old browsers that don't support XHR file uploading. In that case, the jQuery Form plugin switches to the iframe mechanism.
Also, we have already implemented in Drupal's
ajax.jsfile a flagajax_iframe_uploadthat can be read from the PHP side.This bug is not present in Drupal 7 because ajax_deliver takes care of setting the correct header. When Drupal 7 ajax system was removed #1677304: Remove drupal_deliver_page(), ajax_deliver(), drupal_deliver_html_page() I think this was overlooked.
So, we need to recover this important piece of code from Drupal 7's ajax_deliver.
This fix is not only for IE9.
From jQuery file upload wiki FAQ:
I'm not 100% sure if all these browsers need the content-type "text/html", but this is how Drupal 7 was behaving, and there wasn't problems. Also the jQuery Form FAQ suggests that IE is not the only browser.
The patch attached is a reroll of webflo's patch with a couple of changes.
.
Screenshot of IE9 response header and content, after the patch:
Please, review in the patch if it's good to add iframeupload in the file
core/lib/Drupal/Core/EventSubscriber/DefaultExceptionSubscriber.phpComment #32
dawehner@corbacho
Is this still the exact same patch? In case I would still ask what I asked in #30
Comment #33
corbacho commented@dawehner Patch at #31 is addressing your concern
it's the same condition than in
ajax_deliverof Drupal 7Comment #34
dawehnerAfaik the problem is not only for ajax uploads but also for every kind of ajax call, so the if should be around the textarea part of the code?
Comment #35
corbacho commentedThe if is already wrapping the "textarea" part of the code.
Do you mean that setting "Content-Type" to "text/html" is needed for every ajax upload? and should be outside of the if ?
Mhh, I don't think so.
ajax_deliver was behaving like the patch I submitted. And the jquery form plugin also says
Iframe based uploads require a Content-type of text/plain or text/html for the JSON responsein the FAQ (link in #30, where I explain with more details the logic of the patch)Comment #36
dawehnerAh good point, so this is really just related with uploading files.
This issue needs some kind of beta evaluation but beside from this its done.
Comment #37
dawehnerIs this change related to the issue? Beside for that the issue looks RTBC.
Comment #38
corbacho commentedthat code shouldn't be there, indeed. Thanks for catching that Daniel
Comment #39
corbacho commentedcorrect interdiff. (See "reverted" in the top of the interdiff)
Comment #40
dawehnerAdded a beta evaluation.
Comment #41
wim leersDo we need extra docs regarding how we deal with multiple formats using the same MIME types?
Comment #42
corbacho commentedGood point Wim. Or, do you recommend to create a specific mime type for the iframe upload?
With this patch,
$request->getFormat('application/vnd.drupal-ajax')seems to always return the same format (just by looking at source code, not tested)Comment #43
wim leersUnless there's a reason to have it use the same MIME type, I think that'd be better, yes. Bonus from doing that: we can channel our frustration with IE in there.
application/vnd.drupal-ie-lte-9-sucks-beyond-compare, for example.Comment #44
webchickThat sounds like a needs work.
Comment #45
corbacho commentedI find difficult to improve that mime type name
Tested manually in Windows 7 VM - IE9
Comment #47
effulgentsia commentedDo we need that format / mime type at all? If we do, we need to set it somewhere in the JS, but I don't think we do. See attached patch, including its docs.
I don't have a Windows environment handly. @corbacho: can you test this please?
Comment #48
effulgentsia commentedComment #49
corbacho commented@effulgentsia. Yep, it works in IE9
And your comments in the code explains better the bug.
I think this is ready!, but I let someone else to mark it RTBC, to give more time if someone wants to argue this comment:
Thanks!
Comment #50
dawehnerso is this really $_REQUEST or would it be post all the time? Its an upload, so it should be post?
Are we sure we don't accidentally introduce a regression? Is onIframeUpload still called somewhere somehow? What happens if you don't use AjaxResponse but write your own custom implementation for an upload?
Comment #51
dawehnerThe more I think about it, the more I think its a reasonable assumption.
Comment #52
effulgentsia commentedActually, I think #50 brings up good points. I have an idea for one other option for us to consider. Will try to post it today.
Comment #53
Crell commentedI await effulgentsia's alternative, but #47 looks fairly good to me.
Comment #54
webflo commentedPlease note, the last patch does not work. The file upload part is fine but other ajax operations in the same form are failing. jQuery Form adds the
ajax_iframe_uploadflag to the file upload request only. It is not present during any other ajax operations (e.g. field widget with multiple values). IE 9 fails to send the proper accept header if a file upload field is present in the form.Comment #55
dawehnerRight, so the approach to check for an ajax upload is wrong. Given that I think we can RTBC patch #9 which is used in the wild since a LONG time.
Comment #56
alexpottso re-rtbcing an old patch without re-uploading is a bit of a mare from an automated re-test of the rtbc queue point of view. Based #10 pinted out a minor nit with #9 and in #52 @effulgentsia says he has some ideas...
Comment #57
effulgentsia commented@webflo: can you add a comment here with the exact Accept header and POST data that IE 9 sends during a non-file-upload AJAX operation on a form that has a file upload field?
Comment #58
effulgentsia commentedAdditionally, it would also be helpful to know the Accept header it sends during an AJAX operation on a form without any file upload fields.
Comment #59
corbacho commentedI couldn't replicate the bug of @webflo
Patch works. I tried on Article content type, changing the image field to "unlimited", and also testing the autocomplete ajax.

Testing on a Virtual Machine, Windows 7, IE9
@effulgentsia, information you requested:
Default Article content type, uploading an image:
ie9-upload-POST-request.png
Default Article content type, autocomplete request (GET request have empty Request Body, obviously)
ie9-AJAX-GET-request.png
Modified Basic page content type by adding a Unlimited Text Field, clicking "Add another item" (AJAX POST request without file field in the form)
ie9-not-upload-POST-request.png
Full request body: http://pastebin.com/1U1xuF8Z
Comment #60
dawehnerThe problem is something else than you tested. Its about non upload ajax requests in forms which have a file upload element as well.
Comment #61
corbacho commentedI see. It fails, the AJAX response is an HTML document :(
I added a unlimited Text field to Article content type.
Then, clicking "Add another item" makes this request/response:
ie9-non-upload-post-AJAX-with-fileupload-in-the-form.jpg
Comment #62
dawehnerAdapt the issue title to explain directly what is going on wrong.
Comment #63
corbacho commentedAs you saw in the screenshots, the POSTs requests in IE9 has accept header "text/html" always that the form has a File Upload field
We lose our ability to identify what type of Ajax call is (drupal_modal, drupal_ajax, drupal_dialog), because all our ContentNegotiation and renderer is based on mime types.
I made a work-around (1 line in ajax.js), so we can expose the original mime type during the ContentNegotiation phase.
options.extraData.ajax_iframe_upload_mime_type = options.accepts.json + '-iframeupload';I wish someone would have a genius idea to simplify a bit more the patch.
But this currently, works in IE9 and Chrome, and there is not much code duplication, only duplicated mime types.
I've to do more extensive testing, but first, do you agree with the approach?
Comment #64
corbacho commentedneeds review
Comment #65
dawehner@corbacho
To be honest, I don't get why we can't go back to the approach of webflo. Does your patch really fixes the case of having any ajax request in a form with an upload form?
Comment #67
corbacho commented@dawehner I wish too! But weblo's approach worked in *that* time, when the content negotiation and ajax rendering system was different. I tried now similar approach but does not work.
Yes, #63 patch works for all ajax requests types we have been discussing in the issue.
Comment #68
corbacho commentedThe bright side: this "fix" will be removed as soon as we drop IE9 support :)
Comment #69
corbacho commentedSame patch than #63, with fix on test ReadTest.php
Comment #70
larowlannitpick: We don't normally add the extra ',' when the array is on one line - but - an array of over 80 chars should be split according to coding standards.
Real pity about the hardcoding/duplication here but I guess we didn't get #2331919: Implement StackNegotiation so not much we can do.
Manual tests:

Now I'm going to wash in kerosene to remove the traces of IE.
Comment #71
dawehner@corbacho
Its great that you have the motivation to work on this issue, but please be always aware what the actual two problems are we have to solve. Its not just the image upload.
Give it a quick test and it doesn't work yet as expected.
Test instructions:
Instead here is a version of webflo's patch in https://www.drupal.org/node/2339491 which works, see screenshot.
It required an additional fix in
MainContentRenderersPasswhich might the be reason @corbacho could not really follow previousComment #73
dawehnerLet's adapt the test to be a little bit less strict, to not couple to the exact error message.
Comment #74
corbacho commented@dawehner I know that! :)
My patch worked in that scenario too, those were the steps I followed. Did you flush the aggregated JavaScript ? I wonder why didn't work for you.
.. but anyhow... I'm not wasting more time there.. (I'm not that motivated to keep killing hours in IE9).
I like more your patch, that was a smart fix to overload the "drupal_ajax" renderer, and makes everything much simpler :)
Before, every format had a renderer and mimetype associated in a 1:1:1 mapping. Not now, that's why the test failed in #71 returning "null". But I trust that this wouldn't have any further consequences.
The patch offers a fix for the "drupal_ajax" format. My only concern is what happens with drupal_dialog and drupal_modal formats. They have different renderers and arguments, do they keep working as normally when renderer is different ?
Otherwise, thumbs up!
Nitpick: I liked effulgentsia code comment at #47 explaining the bug, we could use it instead of the old one
Comment #75
larowlanMuch cleaner than #70, addresses my whining about duplication.
Let's do it.
Comment #76
dawehnerWhen I tested your patch I recieved a 500 error, this wasn't the JS, pretty sure, hopefully, in case it was, I'm sorry.
This is a good idea in general!
Comment #77
alexpottLet's get the comment from #47 to explain:
Also
What's the answer to this?
Comment #78
dawehnerSure, expanded one part of the comment to include the usecase we struggled with along the way.
Well, but those are only happen on clicking some links, so there is no form involved which leads to an upload form.
On top of that, added some unit test.
Comment #79
corbacho commentedTested in IE9 and Chrome. It works well (image uploads and also unlimited text field 'Add another item' button), well documented and that Unit Test was great great to have :)
Thumbs up!
PS. The content I put in the unlimited text (formatted) field is not saved. But this is not related to this patch, it happens also without the patch. I will open an issue ..
Comment #80
dawehnerOh wow, is that just in IE?
Comment #81
corbacho commentedno, chrome too #2442379: Content of Unlimited Text Field not saved
Anyway, this is unrelated. This shouldn't stop this critical fix to be committed.
Comment #82
alexpottThis issue addresses a critical bug and is allowed per https://www.drupal.org/core/beta-changes. Committed 9c0bfb2 and pushed to 8.0.x. Thanks!
Comment #85
stephenrobinson commentedI did this: