Chrome extension message passing, when xhr call fails in jQuery
I'm building an extension in Google Chrome that issues queries against websites.
The queries are issued by the "background page" on request from the "content script"; when the background page receives a request to issue a query, it sends the query out, parses the response and sends the response back to the content script, using sendResponse().
It all works fine when using XMLHttpRequest(); but my problem is that if I want to issue queries using jQuery .get() or .load(), then when the queries fail, they fail silently and the response is never sent to the content script.
If I register an event handler with .ajaxError() the error is catched, but from this event handler I apparently cannot call sendResponse() because I get the following Chrome error:
"Attempting to use a disconnected port object"
Searching for this error only retrieves the source code for Chrome where this text is found, so it's not very helpful.
In short, my question is: is it possible to use jQuery.get() in a background script of a Chrome extension, and still be able to send a response to the content script when the request fails? (and if yes, how)
This is hard to address directly without a code sample (how were you passing sendResponse
to the error handler?), but I think there are some alternatives to building the XHR yourself.
$.ajax()
: this allows you to specify both a success and an error callback inline; if you can successfully sendResponse
from the success callback, you should also be able to from the error callback. I'd also like to think that you could call sendResponse
from a completely separate function if you stored the sendResponse
function so that it was accessible to the error handler, but maybe you've proven that false already (would love to have seen your code). The documentation makes it sound like the request is open until it's responded to.
After looking at the code to see if I could extract some of it to build a working example (in response to serg comment), I don't think what I want to do is possible with jQuery.
In jQuery, when an ajax call fails, an error event is called (for it to be caught by the .ajaxError() event handler), and then the function ends / returns. When the .ajaxError() handler runs, the function is therefore dead. (That, I believe, is the whole point of the asynchronous event system in JS).
Now, I'm only guessing here, but I think that in Chrome, the communication channel between the content script and the background script is closed when the listener function has run; one cannot send a response from the background script to the content script after the end of the listener function, which is what I was trying to do when handling the ajax error in an event handler.
So, what I ended up doing was re-implement an ajax function that actually sends back a complete object: if the call fails, it returns the fact that there has been an error, together with the error code, so that the caller function (actually a callback) can deal with it and send back a response to the content script.
It's only a few lines, and (I think) quite generic, so here it is:
function xhr(url, callback) {
var req = new XMLHttpRequest();
req.open("GET", url, true);
req.onreadystatechange = function() {
if (req.readyState == 4) {
var resp = {
"url": url,
"status": req.status
};
if (req.status == 200) {
resp.html = req.responseText;
resp.outcome = "ok";
}
else {
resp.outcome = "error";
}
callback(resp);
}
}
req.send(null);
}
链接地址: http://www.djcxy.com/p/91158.html