How do I check if file exists in jQuery or pure JavaScript?

Viewed 526534

How do I check if a file on my server exists in jQuery or pure JavaScript?

19 Answers

I was getting a cross domain permissions issue when trying to run the answer to this question so I went with:

function UrlExists(url) {
$('<img src="'+ url +'">').load(function() {
    return true;
}).bind('error', function() {
    return false;
});
}

It seems to work great, hope this helps someone!

All the other answers can fail due to cache!

Making a HTTP request to a file on server can be intercepted with browser's cache and the cached response is then returned. But the file may be deleted on the server in the meantime, so ignoring cache may return false positive results.

Proper solution would be to create non-cached HTTP HEAD request. Nik Sumeiko's answer uses no-cache header which means that the response can be cached, but must be revalidated before reuse. In this case the server may return 304: Not Modified, which is not 200: OK and thus false negative.

To avoid cache, the correct header is Cache-Control: no-store

File can exist without HTTP 200 response

You should also keep in mind that redirection (301: Moved Permanently, 307: Temporary Redirect or 308: Permanent Redirect) may occur, so the file can exist elsewhere and may be returned from different location: depending on the use-case, one may choose to follow redirection instead of returning false in this case.

Also keep in mind that background requests will be blocked if you check file existence on different domain and its CORS policy is not opened to your server. In this case 403: Forbidden is usually returned, which doesn't mean file does not exist but file is unavailable. Last but not least, the same applies to 500: Internal Server Error response, which means that the HTTP server failed to handle the request, but the file can be available otherwise, like by FTP.

The following code will return true if the file exists, false if not or undefined if the file is unavailable or redirected:

const fileExists = file =>
  fetch(file, {method: 'HEAD', cache: 'no-store'})
  .then(response => ({200: true, 404: false})[response.status])
  .catch(exception => undefined);

fileExists("yourFile.html").then(yes => yes && alert("yourFile.html exists"));

// or in the async scope...
let yourFileExists = await fileExists("yourFile.html");

Modern and obsolete approaches

Since we live in the future now, I would also recommend:

  • $.ajax() obsolete, don't use in new projects
  • XMLHttpRequest() obsolete, don't use in new projects
  • fetch() modern approach, use it if you are free to choose

Note GET/POST methods (like <img src...>) are not appropriate here as they waste network traffic by downloading the file (imagine scenario with high resolution photo and user with paid mobile data or in area with poor connectivity)

Note Modern PWA approach is to use Cache API with serviceWorker's fetch event. In the example in the link, there should be something like

if(event.request.cache=="no-store") return fetch(event.request);

Without this, the cache settings may be ignored and there may be no way to detect the remote file existence from the main thread with the serviceWorker running - illustrated here.

This is an adaptation to the accepted answer, but I couldn't get what I needed from the answer, and had to test this worked as it was a hunch, so i'm putting my solution up here.

We needed to verify a local file existed, and only allow the file (a PDF) to open if it existed. If you omit the URL of the website, the browser will automatically determine the host name - making it work in localhost and on the server:

$.ajax({

    url: 'YourFolderOnWebsite/' + SomeDynamicVariable + '.pdf',
    type: 'HEAD',
    error: function () {
        //file not exists
        alert('PDF does not exist');

    },
    success: function () {
        //file exists
        window.open('YourFolderOnWebsite/' + SomeDynamicVariable + '.pdf', "_blank", "fullscreen=yes");

    }
});

Here's my working Async Pure Javascript from 2020

function testFileExists(src, successFunc, failFunc) {
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function () {
        if (this.readyState === this.DONE) {
            if (xhr.status === 200) {
                successFunc(xhr);
            } else {
                failFunc(xhr);
            }
        }
    }
    // xhr.error = function() {
    //     failFunc(xhr);
    // }
    // xhr.onabort = function() {
    //     failFunc(xhr);
    // }
    // xhr.timeout = function() {
    //     failFunc(xhr);
    // }
    xhr.timeout = 5000;           // TIMEOUT SET TO PREFERENCE (5 SEC)
    xhr.open('HEAD', src, true);
    xhr.send(null);               // VERY IMPORTANT
}
function fileExists(xhr) {
    alert("File exists !!  Yay !!");
}
function fileNotFound(xhr) {
    alert("Cannot find the file, bummer");
}
testFileExists("test.html", fileExists, fileNotFound);

I could not force it to come back with any of the abort, error, or timeout callbacks. Each one of these returned a main status code of 0, in the test above, so I removed them. You can experiment. I set the timeout to 5 seconds as the default seems to be very excessive. With the Async call, it doesn't seem to do anything without the send() command.

It works for me, use iframe to ignore browsers show GET error message

 var imgFrame = $('<iframe><img src="' + path + '" /></iframe>');
 if ($(imgFrame).find('img').attr('width') > 0) {
     // do something
 } else {
     // do something
 }

I wanted a function that would return a boolean, I encountered problems related to closure and asynchronicity. I solved this way:

checkFileExistence= function (file){
    result=false;
    jQuery.ajaxSetup({async:false});
    $.get(file)
        .done(function() {
           result=true;
        })
        .fail(function() {
           result=false;
        })
    jQuery.ajaxSetup({async:true});
    return(result);
},
Related