I'm trying to send an AJAX post request in IE 7, but I'm getting an "Operation Aborted" error, seemingly from the JSON I'm sending, even though everything seems right. I've been messing around with this for an hour or so now, and haven't made any progress, so thought I would post it here to see if anyone could see anything wrong with it.
The "Operation Aborted" error keeps mentioning DOM loading issues, but I only see it when I try to make this post request, so I imagine it's something different in this situation.
var request = new XMLHttpRequest();
request.open("POST", url, false);
request.setRequestHeader("Content-Type", "application/json");
try {
request.send('{"param":"value"}');
} catch (e) {
alert(e.message);
}
It might be that the URL your trying to post data to simply doesn't work on IE7. Try updating to IE8.
http://support.microsoft.com/kb/927917
Stuff like this happens when a script tries to alter an element that hasn't finished loading yet. This website explains it quite well:
http://blogs.msdn.com/b/ie/archive/2008/04/23/what-happened-to-operation-aborted.aspx
changing request.send('{"param":"value"}'); to request.send('{ "param" : "value" }') fixed the issue, sigh.
Related
I want to send an AJAX DELETE request through Javascript when the user closes the tab. The flow is the following:
When the user attempts to close the tab, a onbeforeunload event takes place, then if the user confirms to leave the page the onunload event takes place and tries to execute the deleteRequest function, which is a synchronous ajax delete request.
window.onbeforeunload = function(){
return 'Are you sure you want to leave?';
};
window.onunload = function(){
deleteRequest();
};
function deleteRequest(){
let url = new URL("http://......");
let request = new XMLHttpRequest();
request.onreadystatechange = function () {
if(request.readyState == 4){
if(request.status === 200){
console.log('success');
}
}
}
request.open("DELETE", url, false);
try{
request.send();
}
catch(e){
console.log(e);
}
}
Unfortunately, it seems that Google Chrome does not support anymore this since when a tab closes it kills all the pending events, and in the console of the browser I can see the following message
DOMException: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'http://.....': Synchronous XHR in page dismissal. See https://www.chromestatus.com/feature/4664843055398912 for more details.
at deletRequest(.......js:411:17)
at window.onunload
Please note that I have already seen many topics on this issue before on SO but the solutions did not really help since most of them are out of date since the policy of chrome on this changed quite recently, like this or this.
It seems that most people propose navigator.sendBeacon to achieve this, but in the documentation I saw only ways to make a POST request using this, any thoughts? Thanks in advance.
You're pretty much SOL as far as using sendBeacon out of the box goes, as PUT and DELETE cannot be sent as you observed (only POST). For your XMLHttpRequest, Chrome is very explicit about saying, "hey, we used to send these synchronous XHR requests in beforeunload if you used a no-op loop, but we're not supporting that anymore":
Failed to execute 'send' on 'XMLHttpRequest' [...] Synchronous XHR in page dismissal.
Chrome is intentionally disallowing this behavior. You have no option except to modify the backend, i.e., set up an endpoint that will receive sendBeacon POST request like https://example.com/trigger-delete/ and trigger the DELETE call from the backend, or, if it's not your server, you'll actually have to set up a relay server you control to receive the POST (https://myrelay.com/forward-delete/)and then pass it along as a DELETE.
sendBeacon is the only way you're getting out of this, as far as I can tell.
I'm running some javascript which uses a setInterval to trigger an AJAX request and then performs some actions based on the returned output. I'm quite confused with it, because it works perfectly on my home server, but now that I've put it out onto the web, I'm having problems.
The following error appears on Google Chrome:
http://www.domain.com/ajax/sound.php
Failed to load resource: net::ERR_EMPTY_RESPONSE
The error doesn't occur consistently however. Sometimes the scripts run for several minutes before an error occurs. Sometimes it all breaks down in seconds.
I've already checked the obvious solution - that my server-side script is returning nothing. I did this by commenting out the entire script and having it do nothing but return information. That didn't help.
I have several AJAX requests running from the same page, and all of them eventually return the same error (with their respective pages of code). I've tried isolating the requests and performing them one at a time at a slowed down rate, and have determined that the requests work in a general sense, but as soon as one of them sends an error, they all completely stop working and start sending the same error.
Once the errors occur, I get no response when I try to access any part of my site (even parts with no AJAX). Safari says "...the server unexpectedly dropped the connection. This sometimes occurs when the server is busy. Wait for a few minutes, and then try again." I've tried this in Explorer, Chrome, and Firefox as well with similar results. Thankfully, the site does come back up after a few minutes of making no AJAX requests.
An example of one of the AJAX requests is as follows:
//At the set interval, we create a string for the request:
function alef(){
string = "a='a'";
request(sound, "ajax/sound.php", string);
}
//That function fires off an AJAX request:
function request(fix, url, string){
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
fix(xhttp.responseText);
}
}
xhttp.open("POST", url, true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send(string);
}
//The AJAX request returns a result to be processed by the following function:
function sound(text){
if(text == "sound"){
insound.play();
}
}
Presume that my sound.php files says:
<?php echo "sound"; ?>
It doesn't say only that, but even when it did for testing purposes, I had the same problem.
Any solutions?
I have an XMLHttpRequest opened with the POST method, to a URL that I know exists because I've just done a GET on it.
However, the send() call on the XHR doesn't actually open any connection to the server or send any data -- I've verified this with WireShark.
Instead, it just fails the request, calls the onreadystatechange event handler, setting status to 0 (meaning, according to the spec, that the "error flag" is set).
But... there's no way for me to inspect WHAT is going wrong. I've tried this in FireBug, and the headers and body look OK; there is no response body or response headers. The line in the console output is a POST /url (x) where the (x) is a red circle with an X in it. No error reason is visible anywhere. That same line is not in the NET panel at all. This is probably a clue, but I don't know of what.
function save_edits(url, txt, cb)
{
var xhr = new XMLHttpRequest();
console.log("'POST' " + url);
xhr.open('POST', url, true);
xhr.onreadystatechange = function(ev)
{
if (xhr.readyState == 4)
{
console.log('post complete status:' + xhr.status);
cb();
}
}
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
var text = "&" + edit_what + "=" + escape(txt.replace(/\r/g, '\n'));
try
{
xhr.send(text);
}
catch (e)
{
console.log('send() error: ' + e.toString());
}
This outputs in the FireBug console:
'POST' http://mydomain.com/srv.json.section-xna.latest
POST http://mydomain.com/srv.json.section-xna.latest source.js (line 70)
post complete status:0
Line 1) is my console log statement.
Line 2) is the POST XHR request, which is red, with the circle-X showing failure.
Line 3) is the console log statement from the onreadystatechange handler.
There is no exception raised (I put that check in there just for paranoia) -- even if I make the open() be synchronous instead of asynchronous.
Again, this is not a server-side problem, because the request doesn't even make it onto the wire, and I don't know how to figure out why that is.
Is the URL on your domain or an alternative domain? If it is an alternative domain you are most likely being blocked due to cross domain security issues.
Thanks for the suggestions, everyone! It turns out to be a problem at a higher level.
The code that was calling the save function was then immediately calling window.location.reload() to see the new data, which ended up canceling the outstanding POST request.
Can't believe I had to go through WireShark AND Stack Overflow just to be able to see that problem...
I've got some code that does an ajax request using jQuery, and handles success and error conditions. On an error, I want to find out what the URL I called was, so I can log it. This information appears to be contained in the XMLHttpRequest.channel, but firefox is complaining about accessing this -
Permission denied for <http://localhost:8081> to get property XMLHttpRequest.channel
Any ideas how I can determine the URL associated with an XMLHttpRequest? What's the security issue getting hold of this information? Cheers,
Colin
Ok - sorry about this - an answer is here
http://api.jquery.com/ajaxError/
specifically this code from above link -
$('.log').ajaxError(function(e, xhr, settings, exception) {
if (settings.url == 'ajax/missing.html') {
$(this).text('Triggered ajaxError handler.');
}
});
shows how to access the request url in the event of an ajax error. Doesn't explain why the XMLHttpRequest.channel object is a no go though. Anyway, hopefully that will help others with a similar problem.
Well, you just add it ;]
XMLHttpRequest.prototype.baseOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url, async) { this._url = url; return XMLHttpRequest.prototype.baseOpen.apply(this, arguments); };
then you can later ask for xhr._url in your error handler.
PS: Sorry, just discovered this thread is old.
The security issue is cross domain XHR requests.
In FF2 you used to be able to override this in about:config, also see this blog and especially this preference:
user_pref("capability.policy.default.XMLHttpRequest.channel", "allAccess");
But that's all not possible anymore in FF3. And with a good reason.
Note that XMLHttpRequest.channel is Gecko-specific, so this wouldn't have worked in non-Gecko browsers.
Firebug presents this error with a trace that shows the URI used.
So I have a bit of a problem. When I ask MooTools to send a request it comes back as failed every time. I can't seem to diagnose the problem either because if I try to get the returned header info the console just gives me "Refused to get unsafe header 'Status'" Message. The only thing I can think of is that the server isn't letting me access outside resources but maybe I just coded it wrong.
Here's the request code:
var finfo = current.textFontData();
var url = 'http://antiradiant.com/clients/TMW/rbwizard/mailer.php?s='+current.size+'&b='+current.box+'&l='+current.lidWood+'&c='+current.cartID+'&f='+finfo.font+'&l1='+finfo.line1+'&l2='+finfo.line2;
console.log(url);
var req = new Request({
url: url,
onSuccess: function() {
console.log('success');
//atc2.send();
},
onFailure: function() {
console.log('failure');
console.log(this.getHeader('Status'));
//atc2.send();
},
onException: function(headerName, value) {
console.log('exception');
console.log(headerName+': '+value);
}
});
req.send();
This code is derived from the resource rb_wizard.js (lines 81-103) on http://tylermorriswoodworking.myshopify.com/pages/recipe-box-wizard?b=maple&l=cherry&s=3x5&c=42042892
Mootools has a class called Request.JSONP that will help with your cross domain problem. Its sub class of the Request class, so your methods should work the same. I believe you need to call .post() or .get() at the end instead of send, but thats about all that should chnge. I'm not sure what version you're running on but here is the link tot he docs Mootools Request.JSONP
The error message "Refused to get unsafe header 'Status'" is spat out by WebKit based browsers (Safari, Chrome, etc) when you violate the cross-domain security model.
Therefore, it seems likely that the code you pasted is located on a domain other than antiradiant.com, and therefore is not allowed (by the browser) to request sites on antiradiant.com.
What I ended up doing was just using an iframe. All I really had to do was send data to another site and not receive any so it worked out.