7

All I need is a method that returns true if the Url is responding. Unfortunately, I'm new to jQuery and it's making my attempts at writing that method rather frustrating.

I've seen several examples of jQuery using .ajax, but the code is consistently failing on me. What's wrong?

var urlExists = function(url){
    //When I call the function, code is still executing here.
    $.ajax({
        type: 'HEAD',
        url: url,
        success: function() {
            return true;
        },
        error: function() {
            return false;
        }            
    });
    //But not here...
}
Crescent Fresh
  • 115,249
  • 25
  • 154
  • 140
user474632
  • 311
  • 1
  • 3
  • 11

6 Answers6

25

That isn't how AJAX works. AJAX is fundamentally asynchronous (that's actually what the first 'A' stands for), which means rather than you call a function and it returns a value, instead you call a function and pass in a callback, and that callback will be called with the value.

(See http://en.wikipedia.org/wiki/Continuation_passing_style.)

What do you want to do after you know whether the URL is responding or not? If you intended to use this method like this:

//do stuff
var exists = urlExists(url);
//do more stuff based on the boolean value of exists

Then what you instead have to do is:

//do stuff
urlExists(url, function(exists){
  //do more stuff based on the boolean value of exists
});

where urlExists() is:

function urlExists(url, callback){
  $.ajax({
    type: 'HEAD',
    url: url,
    success: function(){
      callback(true);
    },
    error: function() {
      callback(false);
    }
  });
}
Han Seoul-Oh
  • 1,237
  • 1
  • 12
  • 20
6

urlExists() can not return because it needs wait for the request.

Either pass it a callback, or make it synchronous (not recommended, because it locks the browser).

var urlExists = function(url, callback) {

    if ( ! $.isFunction(callback)) {
       throw Error('Not a valid callback');
    }   

    $.ajax({
        type: 'HEAD',
        url: url,
        success: $.proxy(callback, this, true),
        error: $.proxy(callback, this, false)      
    });

};

Then you can do

urlExists('/something', function(success) {
    if (success) {
        alert('Yay!');
    } else {
        alert('Oh no!');
    }
});

It also worth mentioning the same origin policy.

Also, returning from an anonymous function's scope will not return in the parent function (like in your original example). It just returns that inner function. To return from an inner to a parent, set a flag and return it.

alex
  • 479,566
  • 201
  • 878
  • 984
2

Basically, there is nothing wrong with your code. See it work here: http://jsfiddle.net/PK76X/

My guess is that you're using it to check the availability of content on a different domain, which fails because browsers don't allow cross domain ajax-requests.

Simon
  • 3,509
  • 18
  • 21
  • Funny, that. I managed to get it right except for one important detail. Now I'll have to think of a different method for my site to find the correct address.. – user474632 Nov 29 '10 at 09:04
  • 1
    There is actually a fundamental difference between the code in your jsfiddle and his code: your code will, on success or error, do something (alert, in this case). His code tries to return a value from the original function, which won't work because the original function has already ended by the time the success or error functions are called. Those return statements aren't returning from urlExists(), they're returning from the success and error functions. – Han Seoul-Oh Nov 29 '10 at 18:41
1

If the url is from the same domain as your page you can do it. But if it is from a different domain, for example google.com, then it will fail due to cross domain security.

slebetman
  • 109,858
  • 19
  • 140
  • 171
1

In general, you should probably run your script in Firefox using the firebug plugin. It will give you the details needed to solve the issue.

The ajax and post methods are asynchronous, so you should handle the result in a callback method.

Dan
  • 1,003
  • 1
  • 7
  • 16
-1

AJAX is basically asynchronous, and that's why the behavior you are describing. I've used the following, which is free of cross origin, to get a simple true/false indication whether a URL is valid, in a synchronous manner:

function isValidURL(url) {
    var encodedURL = encodeURIComponent(url);
    var isValid = false;

    $.ajax({
      url: "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22" + encodedURL + "%22&format=json",
      type: "get",
      async: false,
      dataType: "json",
      success: function(data) {
        isValid = data.query.results != null;
      },
      error: function(){
        isValid = false;
      }
    });

    return isValid;
}

The usage is then trivial:

var isValid = isValidURL("http://www.wix.com");
alert(isValid ? "Valid URL!!!" : "Damn...");

Hope this helps

Ohad
  • 242
  • 3
  • 15
  • 1
    While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. – vonbrand May 07 '14 at 21:46
  • Sorry Ohad but your function will return right away before firing success or error because the call to ajax is async. thus the method returns isValid = false immediately after calling ajax(), everytime. have to down vote this one. sorry. – JJ_Coder4Hire Dec 23 '14 at 03:00
  • @JJ_Coder4Hire, Have you tried it? Checkout the ajax call. It states: "async: false" – Ohad Dec 24 '14 at 15:12