Skip to content

Why is it bad to not set the X-request-with XMLHttpRequest for CORS OPTIONS preflight request? #4788

@karendolan

Description

@karendolan

Description

I've been spending a lot of time debugging a Safari oddity with cached CORS images. It doesn't happen in Chrome or Firefox. Safari sends a CORS preflight request on a cached redirect images and the preflight request is rejected because of the nuances of headers and redirects. So, the image doesn't load. And the recommendation is not to use Safari browser for a large number of users. The reason I'm writing a jQuery ticket is that I discovered if add a breakpoint on the xhr.send https://github.com/jquery/jquery/blob/master/src/ajax/xhr.js#L99. And break that send, the image loads no problem. Safari can be used again. For this large user app (Canvas Instructure LMS), the jQuery is v1.7.2.

My Question

In Dec 9, 2010. jaubourg authored and jeresig committed on Dec 9, 2010, a fix that solves my problem here in Sept 2021
"Rewrite of the Ajax module by Julian Aubourg. Some (dated) details can be found here: http://oksoclap.com/6Y26bm1ZsB more details are forthcoming. Fixes #719 "

				// Requested-With header
				// Not set for crossDomain requests with no content
				// (see why at http://trac.dojotoolkit.org/ticket/9486)
				// Won't change header if already provided in beforeSend
				if ( ! ( s.crossDomain && ! s.hasContent ) && ! headers["x-requested-with"] ) {
					headers["x-requested-with"] = "XMLHttpRequest";
				}

ab3ba4a#diff-cb705ccef09991ea3b7663785131bf2dR35-R41

But, then in Mar 6, 2011, that fix was reverted with "Fixes #8423. Never set X-Requested-With header automagically for cross-domain requests." 6c124d3


-					// Requested-With header
-					// Not set for crossDomain requests with no content
-					// (see why at http://trac.dojotoolkit.org/ticket/9486)
-					// Won't change header if already provided
-					if ( !( s.crossDomain && !s.hasContent ) && !headers["X-Requested-With"] ) {
+					// X-Requested-With header
+					// For cross-domain requests, seeing as conditions for a preflight are
+					// akin to a jigsaw puzzle, we simply never set it to be sure.
+					// (it can always be set on a per-request basis or even using ajaxSetup)
+					// For same-domain requests, won't change header if already provided.
+					if ( !s.crossDomain && !headers["X-Requested-With"] ) {
						headers[ "X-Requested-With" ] = "XMLHttpRequest";
					}

Would it be inclusive of both fixes to not add the header if (a) it's a CORS with no content and (b) it's not a CORS,
By combining both fixes in the following?

					// Requested-With header
					// Not set for crossDomain requests with no content
					// (see why at http://trac.dojotoolkit.org/ticket/9486)
					// Won't change header if already provided
					if (( !s.crossDomain ||  !( s.crossDomain && !s.hasContent ))
                                              && !headers["X-Requested-With"] ) {
						headers[ "X-Requested-With" ] = "XMLHttpRequest";
					}

Link to test case

To duplicate:

  1. Open Safari browser
  2. Go to this site https://cidilabs.instructure.com/courses/3/pages/upload-slash-embed-image-test . That link is public and might change. To duplicate the scenario, open a Canvas LMS, upload and image, refresh the page.
  3. Refresh the page to see the broken image link. Refresh a few more times to verify the issue with the broken image request is really stuck.
  4. Open Safari inspector, go to console. Reload the page. See the CORS preflight error.
  5. In Safari inspector, go to the Sources tab, search by type, search for "jquery" under node_modules/jquery path.
  6. In the jquery source, place a breakpoint on line 7487 "xhr.send( ( s.hasContent && s.data ) || null );"
  7. reload the page and let it debugger hang at your breakpoint.
    After a bit, the image will load. Thereafter, reloading that page will load the image.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions