Bug Tracker

Ticket #7653 (closed bug: fixed)

Opened 4 years ago

Last modified 2 years ago

XHR requests in Chrome and Safari extension pages return xhr.status === 0

Reported by: fam.lam@… Owned by: jaubourg
Priority: low Milestone: 1.5.1
Component: ajax Version: 1.4.4
Keywords: Cc:
Blocking: Blocked by:

Description

An XHR request will get 'status' set to 0, when you are on a extension page on Chrome and Safari...

This used to work fine until 1.4.3 was released... Geki007 found the reason to be
===============
in jquery dev build search httpSuccess: function( xhr ) {

here now are 2 different solutions:
add || xhr.status === 0 ... this was in jquery 1.4.2
or add || location.protocol === "chrome-extension:"
=======================

However, this won't work for safari extensions.

My suggestion is to change (near line 6200)

// Determines if an XMLHttpRequest was successful or not
httpSuccess: function( xhr ) {
	try {
		// IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
		return !xhr.status && location.protocol === "file:" ||
			xhr.status >= 200 && xhr.status < 300 ||
			xhr.status === 304 || xhr.status === 1223;
	} catch(e) {}
	return false;
},

into

// Determines if an XMLHttpRequest was successful or not
httpSuccess: function( xhr ) {
	try {
		// IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
		return !xhr.status && (location.protocol === "file:" ||
			location.protocol.indexOf('-extension:') != -1) ||
			xhr.status >= 200 && xhr.status < 300 ||
			xhr.status === 304 || xhr.status === 1223;
	} catch(e) {}
	return false;
},

or

// Determines if an XMLHttpRequest was successful or not
httpSuccess: function( xhr ) {
	try {
		// IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
		return !xhr.status && (location.protocol === "file:" ||
			location.protocol === 'chrome-extension:' ||
			location.protocol === 'safari-extension:') ||
			xhr.status >= 200 && xhr.status < 300 ||
			xhr.status === 304 || xhr.status === 1223;
	} catch(e) {}
	return false;
},

Due to this bug we (AdBlockforChrome) cannot update to JQuery 1.4.3 or 1.4.4.

Change History

comment:1 Changed 4 years ago by paul.irish

Just for clarity, can you describe what the result of the xhr.status === 0 is? httpSuccess fails when it shouldn't? The reverse? Just knowing the context here would help.

comment:2 Changed 4 years ago by paul.irish

comment:3 Changed 4 years ago by anonymous

Yes, in the extension pages xhr.status is always 0, even if it succeeds. I know that it should have a succeed code given by the browser (therefore the chrome bug and safari bug report).

If you put a breakpoint in the httpSuccess function you will notice the correct text is returned.

These are the properties of xhr in that code according to the element inspector: {{{xhr: XMLHttpRequest

abort: function () { onabort: null onerror: null onload: null onloadstart: null onprogress: null onreadystatechange: function () {} readyState: 4 responseText: " <script> $(function() { Check or uncheck each option. extension_call('get_optio…" responseXML: null status: 0 statusText: "" upload: XMLHttpRequestUpload withCredentials: false proto: XMLHttpRequest

}}} As you can see everything is correct, except for the status. Chrome (and Safari) always return 0 as status in the extension pages...

comment:4 Changed 4 years ago by snover

  • Priority changed from undecided to low
  • Resolution set to patchwelcome
  • Status changed from new to closed
  • Component changed from unfiled to ajax

Unfortunately, according to the XMLHttpRequest spec, status 0 is reserved for network failures or aborts, so a successful AJAX request should never return a status code of 0. Doing so makes it impossible for the library to differentiate between successful and failed requests. This was actually an issue in jQuery 1.4.0-1.4.2; see ticket #6060 for background.

What I would probably recommend is for you to switch to using synchronous requests if you are loading data from the extension’s own bundle, at least until this is fixed in Chrome.

If you can figure out a patch that fixes this problem without breaking the ability to differentiate a network failure from a successful request and without checking for the chrome-extension protocol, we would be happy to look into adding it to the next version of jQuery.

comment:5 Changed 4 years ago by FamLam <fam.lam@…>

What about this:

|| (xhr.status === 0 && xhr.responseText)

comment:6 Changed 4 years ago by FamLam <fam.lam@…>

 http://code.google.com/p/chromium/issues/detail?id=64594#c5

Chrome says this is the normal behaviour.

comment:7 Changed 4 years ago by jaubourg

  • Status changed from closed to reopened
  • Resolution patchwelcome deleted

comment:8 Changed 4 years ago by jaubourg

  • Owner set to jaubourg
  • Status changed from reopened to assigned
  • Milestone changed from 1.6 to 1.5.1

comment:9 Changed 4 years ago by jaubourg

  • Status changed from assigned to closed
  • Resolution set to fixed

Fixes #7653. Changes regexp to detect local protocol so that it will accept any protocol finishing by -extension.

Changeset: 50e950a96e0fae23a1ae418951a298e2949ff351

comment:10 Changed 4 years ago by jaubourg

It should work now. Any confirmation/infirmation is welcome.

comment:11 Changed 4 years ago by FamLam <fam.lam@…>

I assume I should test it with  http://code.jquery.com/jquery-git.js

If so, I get

uncaught TypeError: Cannot read property '1' of null

at line 6295

        isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),

comment:12 Changed 4 years ago by FamLam <fam.lam@…>

The fix for the issue described above would be to modify the regex rurl to

rurl = /^([\w\-]+:)\/\/([^\/?#:]*)(?::(\d+))?/,

As the urls of both safari and Chrome extensions are chrome-extension://* safari-extension://*

Because at the moment the regex doesn't match because of the '-' in the protocol.

comment:14 Changed 4 years ago by FamLam <fam.lam@…>

It works good now! Thank you!

Note: See TracTickets for help on using tickets.