92

I am trying to hook up a script to Microsoft's World-Wide Telescope app. The latter listens on port 5050 for commands. It is running on the same machine as the browser (Chrome right now, but as far as I can tell the behavior is the same with Firefox 7 and IE 9).

I am sending a "Access-Control-Allow-Origin: *" header with the original html file to try to eliminate XSS restrictions as my problem.

My code to access WWT is as follows:

$.ajax({
    type: 'POST',
    url: url,
    data: data,
    crossDomain: true,
    success: success,
    dataType: dataType
});

url in this case is "http://127.0.0.1:5050/layerApi.aspx?cmd=new&..." (obviously ... is shorthand here for some additional parameters).

Looking at the network diagnostics in Chrome, I can see this:

Request URL:http://127.0.0.1:5050/layerApi.aspx?cmd=new&...
Request Headersview source
Accept:application/xml, text/xml, */*; q=0.01
Content-Type:application/x-www-form-urlencoded
Origin:http://gwheeler4
Referer:http://gwheeler4/conceptconnect.html
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.186 Safari/535.1

The request is going out - I see WWT make a new layer. However, I don't get a callback. If I add an error callback that gets called, but the error property on the jqXHR object is just "error" and status is 0. If I look at the network request in Chrome I see "(cancelled)" as the status and no response.

If I take that same URL and paste it in a new browser tab, I can see that the response is the expected XML.

Of course, a difference here is that this is a GET not a POST, but I've tried that in my script and it makes no difference.

I'm pretty stumped by this and would appreciate any fresh ideas.

j0k
  • 22,600
  • 28
  • 79
  • 90
Graham Wheeler
  • 2,734
  • 1
  • 19
  • 23
  • Have you tried handling the `error` callback to see if it's returning with an error? – StriplingWarrior Sep 28 '11 at 01:08
  • 1
    "I am sending a "Access-Control-Allow-Origin: *" header with the original html file to try to eliminate XSS restrictions as my problem." Do you mean that the server is sending back the Access-Control-Origin header? Or that you are sending it along with the Ajax request? – Jason Dean Sep 28 '11 at 01:37
  • try accessing the page directly through url and see are you getting any out – zod Sep 28 '11 at 03:38
  • 1
    Yes, I get an error callback with status text "" and code 0. This isn't a jQuery issue; I rewrote the code using a straight XHR and I get the same result - i.e. a readyState of 4 with a request.status of zero and an empty request.responseText. The Access-Control-Allow-Origin header is being sent by the server. Accessing the page directly through the URL returns the expected XML response. – Graham Wheeler Sep 28 '11 at 20:46

18 Answers18

138

If anyone else runs into this, the issue we had was that we were making the ajax request from a link, and not preventing the link from being followed. So if you are doing this in an onclick attribute, make sure to return false; as well.

Kazetsukai
  • 2,268
  • 1
  • 14
  • 16
  • This worked for me too. Thanks. I forgot why I was returning false in my onClick handler, and changed it to true, and after reading your post, it suddenly dawned on me. – Shiprack Oct 21 '12 at 04:33
  • 4
    Additionally, if you are using a form you need to add the `return false` at the end of you `onsubmit` attribute. – Jason Axelson Feb 26 '13 at 21:27
  • Just wanted to pass by to say Thank you a million times. I am using Ext JS Sencha and using the ajax call at launch function and when i put the return false I was able to achieve this can somebody explain why the return false was fix. I have a little idea though but want to know more about this – Clyde Aug 13 '13 at 13:19
  • 8
    @VincentClyde `"return false;"` tells forms and links to abort the action. This was originally intended for javascript form validation, where a validate function would return false if the form was invalid, stopping the form from submitting. – Tyzoid Aug 19 '13 at 15:46
  • 14
    You can also use `e.preventDefault();`, where `e` is the `onclick` event parameter. – Hannele Jun 12 '14 at 15:21
  • where exactly should I return false or put e.preventDefault()?? Thanks for clarifying :) – Tim Apr 14 '15 at 22:11
  • Many thanks - it's far too easy to forget about returning false – Dan Jul 22 '16 at 18:46
  • Brilliant! Spent several hours for solving this out. Thanks a lot! – Maksim Sep 17 '16 at 20:17
  • It seems that the request gets sent as expected, but it is the browser's result-handling that gets cancelled on page reload. We have an app with tracking calls on links, so `e.preventDefault()` is not an option. The events get tracked fine though, since the tracking call's response is ignored anyway. – Trevedhek Nov 23 '17 at 22:18
  • For me it's because of adblock – Luvias Dec 27 '17 at 16:12
  • If using React, then it needs to be e.preventDefault() see: https://reactjs.org/docs/handling-events.html – Mark Adamson Jan 26 '18 at 21:56
  • This also applies if you fire off two ajax calls and they both fire callback, make sure that your success callback also return false, that's what got me. When I added a return false to my first ajax callback, the second started working and stopped "cancelling". hehe, "return false" it's not just for on-click anymore :) – Severun Feb 05 '18 at 21:13
  • 1
    @Hannele Thank you so much for sharing event.preventDefault. I needed it so badly. I don't see any other answer suggesting this. You should post this as separate answer. – Mohit Apr 18 '18 at 14:24
114

If you're using Chrome you can't see enough information in the standard Chrome networking panel to determine the root cause of a (canceled) request.

You need to use chrome://net-internals/#events which will show you the gory detail of the request you are sending - including hidden redirects / security information about cookies being sent etc.

e.g. the following shows a redirect I wasn't seeing in the network trace - caused by my cookies not being sent cross sub-domain:

t=1374052796448 [st=  1]   +URL_REQUEST_START_JOB  [dt=261]
                            --> load_flags = 143540481 (DO_NOT_SAVE_COOKIES | DO_NOT_SEND_AUTH_DATA | DO_NOT_SEND_COOKIES | ENABLE_LOAD_TIMING | MAYBE_USER_GESTURE | REPORT_RAW_HEADERS | VALIDATE_CACHE | VERIFY_EV_CERT)
                            --> method = "GET"
                            --> priority = 2
                            --> url = "https://...."
...
t=1374052796708 [st=261]        HTTP_TRANSACTION_READ_RESPONSE_HEADERS
                                --> HTTP/1.1 302 Moved Temporarily
                                    Content-Type: text/html
                                    Date: Wed, 17 Jul 2013 09:19:56 GMT
...
t=1374052796709 [st=262]     +URL_REQUEST_BLOCKED_ON_DELEGATE  [dt=0]
t=1374052796709 [st=262]        CANCELLED
t=1374052796709 [st=262]   -URL_REQUEST_START_JOB
                            --> net_error = -3 (ERR_ABORTED)
Ben Walding
  • 4,006
  • 2
  • 30
  • 28
  • I also have a (cancelled) problem. @Ben, it was cool to learn about this trace, unfortunately it did not provide any info. Server in my case is S3 and cors is configured on my bucket. All I am doing is a simple GET for an image. I see in a network panel a request with the Origin header, but no response. Apparently Chrome cancels the request before sending it to the server. No redirects, no https, no content-lenght 0. Banging my head all day, still a mystery. – Gene Vayngrib Sep 18 '13 at 04:16
  • @GeneVayngrib Try Firefox - the network debugger will directly show more information - you might be able to resolve the issue there and then get it working in Chrome. – Ben Walding Sep 19 '13 at 05:06
  • @BenW thank you, but Firefox has no problem with this image that is served from Amazon S3. – Gene Vayngrib Sep 19 '13 at 18:53
  • YUPP. That helped alot! – rubmz Jun 06 '18 at 20:35
28

In my case I was having type='submit' so when I was submitting the form the page was reloading before the ajax hit going so a simple solution was to have type="button". If you don't specify a type it's submit by default so you've gotta specify type="button"

type='submit' => type='button'

OR

No type => type='button'

Or if you don't want to change the type or submit the form on click you can e.preventDefault() as the very first thing e.

<button>Submit</button>
 
<script>
$( "button" ).click(function( event ) {
  event.preventDefault();
  // AJAX Call here
});
</script>
Black Mamba
  • 13,632
  • 6
  • 82
  • 105
  • 4
    necro posting on here, sue me stackoverflow. I've been searching high and low all day for why my request works from the console but not the script, and this was the answer.. thank you!!! – pcort May 07 '19 at 17:33
  • 2
    I logged in and found this thread again to upvote this answer!!, this helped a lot. was breaking my head for hours – dev Jul 22 '20 at 14:15
  • Jai shree krishna, hope it helps many to come. And they figure out earlier. – Black Mamba Jul 22 '20 at 18:01
6

I had a similar problem. In my case, I'm trying to use a web service on a apache server + django (the service was written by myself). I was having the same output as you: Chrome says it was cancelled while FF does it okay. If I tried to access the service directly on the the browser instead of ajax, it would work as well. Googling around, I found out that some newer versions of apache weren't setting the length of the response correctly in the response headers, so I did this manually. With django, all I had to do was:

response['Content-Length'] = len(content)

If you have control over the service you are trying to access, find out how to modify the response header in the platform you are using, otherwise you'd have to contact the service provider to fix this issue. Apparently, FF and many others browsers are able to handle this situation correctly, but Chrome designers decided to do it as specified.

  • I tried setting the content-length header, and still have the same problem as described in the original question. I'm using PHP 5.3.8 and Apache 2.2.21 (using WAMP in Windows 7) – rodrigo-silveira May 20 '12 at 01:46
5

Two possibilities are there when AJAX request gets dropped (if not Cross-Origin request):

  1. You are not preventing the element's default behavior for the event.
  2. You set timeout of AJAX too low, or network/application backend server is slow.

Solution for 1): Add return false; or e.preventDefault(); in the event handler.

Solution for 2): Add timeout option while forming the AJAX request. Example below.

$.ajax({
    type: 'POST',
    url: url,
    timeout: 86400,
    data: data,
    success: success,
    dataType: dataType
});

For Cross-origin requests, check Cross-Origin Resource Sharing (CORS) HTTP headers.

AnkitK
  • 388
  • 3
  • 10
4

I had a similar issue. Using chrome://net-internals/#events I was able to see that my issue was due to some silent redirect. My get request was being fired in an onload script. The url was of the form, "http://example.com/inner-path" and the 301 was permanently redirecting to "/inner-path". To fix the issue I just changed the url to "/inner-path" and that fixed the issue. I still don't know why a script that worked a week ago was suddenly giving me issue... Hope this helps someone

RedEight
  • 121
  • 1
  • 5
3

(Using Web Forms ASP.NET)

My issue was I was trying to fire Ajax off the click event of a submit button that had a server side click event setup. I had to make the button just a simple button (i.e. <input type="button"> )

contactmatt
  • 18,116
  • 40
  • 128
  • 186
3

I have had the same problem, for me I was creating the iframe for temporary manner and I was removing the iframe before the ajax become completes, so the browser would cancel my ajax request.

Reza
  • 18,865
  • 13
  • 88
  • 163
  • How did you solve this issue ?My site is getting embedded in an iFrame not controlled by me.I want my call to be completed as it does some background data setting – Rips Jun 14 '20 at 08:41
  • @Rips this is for 4 years ago, anyway I think I solved it by using Promises – Reza Jun 14 '20 at 15:36
3

Expanding on @Kazetsukai's answer, you may run into this problem if you are making your AJAX request from the user clicking on a link.

If you set up your link like so:

<a href="#" onclick="soAjax()">click me!</a>

And then a javascript handler like the following:

soAjax() {
    $.ajax({ ... all your lovely parameters ... });       
}

To prevent your browser from following the link and cancelling any requests in progress, you should add return false or e.preventDefault() to stop the click event from propagating:

soAjax() {
   $.ajax({ ... etc ... });
   return false;
}

Or:

soAjax(e) {
   $.ajax({ ... etc ... });
   e.preventDefault();
}
Hannele
  • 9,301
  • 6
  • 48
  • 68
2

For Dropzone.js case. In my case it's was caused because of timeout option value was too low by default. So increase it by your needs.

{
// other dropzone options
timeout: 60000 * 10, // 10 minutes
...
}
Scofield
  • 4,195
  • 2
  • 27
  • 31
1

I got this error when making a request using http to a url that required https. I guess the ajax call is not handling the redirection. This is the case even with the crossDomain ajax option set to true (on JQuery 1.5.2).

ptutt
  • 1,338
  • 3
  • 18
  • 35
0

In my case, I Apache's mod-rewrite was matching the url and redirecting the request to https.

Look at the request in chrome://net-internals/#events.

It will show an internal log of the request. Check for redirects.

bbrame
  • 18,031
  • 10
  • 35
  • 52
0

I had the same problem, but in my case it turned out to be a cookie issue. The guys working on the back-end had changed the path of the JSESSIONID cookie that's set when we log in to our app, and I had an old cookie by that name on my computer, but with the old path. So when I tried logging in the browser (Chrome) sent two cookies called JSESSIONID, with different values, to the server - which understandably confused it - so it cancelled the request. Deleting the cookies from my computer fixed it.

Joe Dyndale
  • 1,073
  • 1
  • 15
  • 32
0

I had this error in a more spooky way: The network tab and the chrome://net-internals/#events did not show the request after the js was completed. When pausing the js in the error callcack the network tab did show the request as (cancelled). The was consistently called for exactly one (always the same) of several similar requests in a webpage. After restarting Chrome the error did not rise again!

Christian
  • 13,285
  • 2
  • 32
  • 49
0

I had the cancelled in Firefox. Some ajax-calls working perfectly fine for me, but it failed for the coworker who actually had to use it.

When I checked this out via the Chrome tricks mentioned above, I found nothing suspicious. When checking it in firebug, it showed the 'loading' animation after the two mallicous calls, and no result tab.

The solution was mega simple: go to history, find the website, rightclick -> forget website.
Forget, not delete.

After that, no problems anymore. My guess is it has something to do with the .htaccess.

Martijn
  • 15,791
  • 4
  • 36
  • 68
0

In my case, it was the missing trailing slash in the url. Adding the trailing slash solved my problem.

Aftab Baig
  • 279
  • 5
  • 16
0

Check for page reloads.

Problem:

In my case I was reloading the page using location.reload() inside click event, before Ajax being fired. Also, there was second Ajax call in the success.

Solution:

I removed the the reload and put it inside success callback of last Ajax call and it worked.

bareMetal
  • 425
  • 1
  • 7
  • 20
-1

I had this issue with a particular 3G network.
It would always fail on DELETE requests with net_error = -101 in chrome://net-internals/#events.

Other networks worked just fine so I assume there was a faulty proxy server or something.

Dan Abramov
  • 264,556
  • 84
  • 409
  • 511