Jak sprawdzić, czy plik istnieje w jQuery lub czystym JavaScript?

259

Jak sprawdzić, czy plik na moim serwerze istnieje w jQuery lub czystym JavaScript?

test użytkownika
źródło

Odpowiedzi:

433

Z jQuery:

$.ajax({
    url:'http://www.example.com/somefile.ext',
    type:'HEAD',
    error: function()
    {
        //file not exists
    },
    success: function()
    {
        //file exists
    }
});

EDYTOWAĆ:

Oto kod do sprawdzania statusu 404 bez użycia jQuery

function UrlExists(url)
{
    var http = new XMLHttpRequest();
    http.open('HEAD', url, false);
    http.send();
    return http.status!=404;
}

Małe zmiany i może zamiast tego sprawdzić status kod statusu HTTP 200 (sukces).

EDYCJA 2: Ponieważ synchronizacja XMLHttpRequest jest przestarzała, możesz dodać taką metodę narzędzia, aby wykonać to asynchronicznie:

function executeIfFileExist(src, callback) {
    var xhr = new XMLHttpRequest()
    xhr.onreadystatechange = function() {
        if (this.readyState === this.DONE) {
            callback()
        }
    }
    xhr.open('HEAD', src)
}
cichy
źródło
5
w przykładzie czystego javascript powinieneś być wiążącym OnReadyStateChangezdarzeniem przed sprawdzeniem HTTP_STATUS.
RobertPitt,
8
Przykładowy kod jest niepoprawny i nic nie mówi o tym, co dzieje się na serwerze. Pierwotne pytanie jest dość niejasne, ale nie ma powodu, aby zakładać, że uruchomiony tam serwer faktycznie mapuje adresy URL bezpośrednio do systemu plików. Szczerze mówiąc, nie rozumiem, dlaczego ta odpowiedź jest tak popularna, ponieważ tak naprawdę nie mówi, jak postępować zgodnie z pytaniem.
Pointy,
75
@Pointy Może być tak, ponieważ rozwiązuje to problem, dla którego reszta z nas poszukuje Googling
Ian Hunter
4
@cichy - czy to ładuje plik do pamięci, czy nie? Chcę sprawdzić istnienie, ale nie załadować pliku.
Brian
11
Synchroniczne XMLHttpRequest w głównym wątku jest przestarzałe ze względu na jego szkodliwy wpływ na doświadczenie użytkownika końcowego. Aby uzyskać dodatkową pomoc xhr.spec.whatwg.org (To ostrzeżenie przez przeglądarkę)
kupendra
71

Podobne i bardziej aktualne podejście.

$.get(url)
    .done(function() { 
        // exists code 
    }).fail(function() { 
        // not exists code
    })
Matthew James Davis
źródło
2
dlaczego jest to bardziej aktualne? $.ajaxwydaje się lepszy, jeśli jest bardziej kompatybilny wstecz, prawda?
tim peterson
15
$ .ajax też działa, ale funkcje sukces / błąd / pełne są przestarzałe na rzecz obietnic, metod done / fail / always. czytaj więcej na ten temat tutaj api.jquery.com/jQuery.ajax . Użyłem tutaj get, ponieważ interesuje nas tylko prosty get, ale jest to tylko skrót dla $ .ajax ({url: url, wpisz: 'GET'}).
Matthew James Davis,
4
Jeśli obraz nie istnieje, echo konsoli oznacza błąd 404. Czy istnieje sposób na usunięcie tego, ponieważ moja aplikacja zawsze oczekuje, że jeden obraz nie będzie istniał ...
user1534664 24.09.2013
1
Niemożliwe, patrz: stackoverflow.com/a/16379746/1981050 . Nie powinno to jednak zakłócać twojego zachowania. To po prostu przyniesie zbędne rejestrowanie.
Matthew James Davis,
1
kwestie pochodzenia krzyżowego nie są z tym związane
Matthew James Davis
69

To działa dla mnie:

function ImageExist(url) 
{
   var img = new Image();
   img.src = url;
   return img.height != 0;
}
Próbnik
źródło
2
Podczas gdy niektóre inne odpowiedzi są lepsze dla ich funkcji, daję +1 tej odpowiedzi, ponieważ tego właśnie szukałem. Pamiętaj tylko, że zawsze otrzymasz zero, chyba że najpierw załadujesz zawartość !. tj .: window.addEventListener ('load', function () {
SpiRail
Właściwie nadal miałem problemy, nawet przy obciążeniu okna. Wygląda na to, że obrazu nie można zmierzyć, dopóki nie zostanie w jakiś sposób buforowany. W każdym razie nie działam dla mnie przy pierwszym ładowaniu strony. (tzn .: użytkownik nigdy wcześniej nie widział tego obrazu). Może ci się przydać, jeśli masz obraz na poprzedniej stronie, może ...
SpiRail
3
Jest tak, ponieważ ustawia źródło obrazu i NATYCHMIAST sprawdza, czy wysokość obrazu nie została jeszcze zakończona. Aby to zadziałało, musisz dodać moduł obsługi obciążenia. Z tego właśnie powodu nie jest to wiarygodne podejście.
dudewad
Dlaczego nie jest niezawodny, jeśli dodasz program img.onload, taki jak stackoverflow.com/a/12355031/988591 ?
jj_
3
Pytanie dotyczy pliku , a nie obrazu! Jeśli adres URL istnieje i nie jest plikiem, jego wysokość będzie wynosić 0 !!
Apostolos
44

użyłem tego skryptu, aby dodać alternatywny obraz

function imgError()
{
alert('The image could not be loaded.');
}

HTML:

<img src="image.gif" onerror="imgError()" />

http://wap.w3schools.com/jsref/event_onerror.asp

Gino
źródło
24
Świetnie - nie wiedziałem o tym. Możesz wykonać następujące czynności, aby ustawić alternatywę zapisu, jeśli obraz nie istnieje: <img src = "image.gif" onerror = "this.src = 'alternative.gif'">
Ridcully
2
@Ridcully Ah, ale co, jeśli alternatywa zawiedzie? Jesteś w niekończącej się pętli, prawda?
rvighne
Jeśli alternatywa zawiedzie, przypuszczam, że po stronie serwera (lub po stronie programisty: P) dzieje się coś jeszcze nie tak
Erenor Paz
Zawsze można ustawić wartość OnError znacznika img na nic podczas ustawiania obrazu alt, aby zapobiec niekończącej się pętli.
KingOfHypocrites
Świetna robota. Działa jak marzenie.
zatrudniony
24

Dopóki testujesz pliki w tej samej domenie, powinno to działać:

function fileExists(url) {
    if(url){
        var req = new XMLHttpRequest();
        req.open('GET', url, false);
        req.send();
        return req.status==200;
    } else {
        return false;
    }
}

Uwaga: w tym przykładzie użyto żądania GET, które oprócz pobrania nagłówków (wszystko, czego potrzebujesz, aby sprawdzić, czy plik istnieje), pobiera cały plik. Jeśli plik jest wystarczająco duży, wykonanie tej metody może trochę potrwać.

Lepszym sposobem na to byłoby zmiana tej linii: req.open('GET', url, false);nareq.open('HEAD', url, false);

Moob
źródło
5
Przepraszamy, jest to w rzeczywistości to samo, co zaakceptowana odpowiedź. Ignoruj ​​mnie.
Moob
1
jest więcej szczegółów na temat formularza nie-jQuery, który może być pomocny
tim peterson
@Moob, nie jest „efektywnie taki sam jak zaakceptowana odpowiedź”, wysyłasz żądanie GET, które różni się znacznie od żądania HEAD.
YemSalat
async: false, synchroniczne działanie w przeglądarce Firefox w wersji 30.0 i nowszych oraz w najnowszych / bieżących wersjach Chrome jest przestarzałe ze względu na niekorzystne wrażenia użytkownika. Próba użycia powoduje błąd / błąd. Należy używać async: truez funkcją wywołania zwrotnego do działania asynchronicznego.
Kevin Fegan
Proszę poczekać na odpowiedź przed kontynuowaniem wykonywania JS? Dziękuję Ci.
vladanPro
16

Podczas próby uruchomienia odpowiedzi na to pytanie otrzymywałem problem z uprawnieniami między domenami, więc wybrałem:

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

Wygląda na to, że działa świetnie, mam nadzieję, że to komuś pomoże!

Shaun
źródło
3
Myślę, że spowoduje to utratę wartości boolowskich, ponieważ zostaną zwrócone przez wywołania zwrotne, a nie funkcję UrlExists.
mikebridge
to nie może działać, powinieneś przeczytać to: stackoverflow.com/questions/14220321/...
Hacketo
jak wygląda adres URL? , z przedłużeniem czy bez przedłużenia?
151291
10

Oto jak to zrobić ES7, jeśli używasz transpilatora Babel lub Typescript 2:

async function isUrlFound(url) {
  try {
    const response = await fetch(url, {
      method: 'HEAD',
      cache: 'no-cache'
    });

    return response.status === 200;

  } catch(error) {
    // console.log(error);
    return false;
  }
}

Następnie w swoim drugim asynczakresie możesz łatwo sprawdzić, czy adres URL istnieje:

const isValidUrl = await isUrlFound('http://www.example.com/somefile.ext');

console.log(isValidUrl); // true || false
Nik Sumeiko
źródło
5

Używam tego skryptu, aby sprawdzić, czy plik istnieje (obsługuje także problem krzyżowego pochodzenia):

$.ajax(url, {
       method: 'GET',
       dataType: 'jsonp'
         })
   .done(function(response) { 
        // exists code 
    }).fail(function(response) { 
        // doesnt exist
    })

Zauważ, że następujący błąd składniowy jest generowany, gdy sprawdzany plik nie zawiera JSON.

Uncaught SyntaxError: Nieoczekiwany token <

Gëzim Musliaj
źródło
3

Wywołanie asynchroniczne, aby sprawdzić, czy plik istnieje, jest lepszym rozwiązaniem, ponieważ nie pogarsza wrażeń użytkownika, czekając na odpowiedź z serwera. Jeśli wykonasz wywołanie .openz trzecim parametrem ustawionym na false (jak na przykład w wielu przykładach powyżej)http.open('HEAD', url, false); ), jest to połączenie synchroniczne i pojawi się ostrzeżenie w konsoli przeglądarki.

Lepszym podejściem jest:

function fetchStatus( address ) {
  var client = new XMLHttpRequest();
  client.onload = function() {
    // in case of network errors this might not give reliable results
    returnStatus( this.status );
  }
  client.open( "HEAD", address, true );
  client.send();
}

function returnStatus( status ) {
  if ( status === 200 ) {
    console.log( 'file exists!' );
  }
  else {
    console.log( 'file does not exist! status: ' + status );
  }
}

źródło: https://xhr.spec.whatwg.org/

Jim Bergman
źródło
Dostaję również ostrzeżenie w dzienniku konsoli z twoją metodą, jakiś pomysł?
Pierre
Spróbuj zadzwonić .openz trzecim zestawem parametrów, trueaby upewnić się, że wywołuje go asynchronicznie, na przykład client.open("HEAD", address, true);@Pierre
Jim Bergman
2

W przypadku komputera klienckiego można to osiągnąć poprzez:

try
{
  var myObject, f;
  myObject = new ActiveXObject("Scripting.FileSystemObject");
  f =   myObject.GetFile("C:\\img.txt");
  f.Move("E:\\jarvis\\Images\\");
}
catch(err)
{
  alert("file does not exist")
}

To jest mój program do przesyłania pliku do określonej lokalizacji i wyświetla alert, jeśli nie istnieje

yasir amin 9th-b DR.VSMPS
źródło
1
Jeśli zamierzasz użyć FileSystemObject, łatwiej jest użyć metody FileExists (). msdn.microsoft.com/en-us/library/aa265024(v=vs.60).aspx
Mark F Guerra
2

Funkcja JavaScript, aby sprawdzić, czy plik istnieje:

function doesFileExist(urlToFile)
{
    var xhr = new XMLHttpRequest();
    xhr.open('HEAD', urlToFile, false);
    xhr.send();

    if (xhr.status == "404") {
        console.log("File doesn't exist");
        return false;
    } else {
        console.log("File exists");
        return true;
    }
}
Ani Menon
źródło
1

Najpierw tworzy funkcję

$.UrlExists = function(url) {
	var http = new XMLHttpRequest();
    http.open('HEAD', url, false);
    http.send();
    return http.status!=404;
}

Po użyciu funkcji w następujący sposób

if($.UrlExists("urlimg")){
	foto = "img1.jpg";
}else{
	foto = "img2.jpg";
}

$('<img>').attr('src',foto);

Vladimir Salguero
źródło
Próbowałem tutaj, ale nie udało mi się. Czego mi brakowało?
Chetabahana
1

To jest dostosowanie do zaakceptowanej odpowiedzi, ale nie mogłem uzyskać tego, czego potrzebowałem od odpowiedzi, i musiałem przetestować, czy zadziałało, ponieważ było przeczucie, więc tutaj zamieszczam moje rozwiązanie.

Musieliśmy sprawdzić, czy plik lokalny istnieje i zezwolić na otwarcie pliku (PDF) tylko wtedy, gdy istnieje. Jeśli pominiesz adres URL witryny, przeglądarka automatycznie określi nazwę hosta - dzięki czemu będzie działać w localhost i na serwerze:

$.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");

    }
});
Josh Harris
źródło
0

To, co musisz zrobić, to wysłać do serwera żądanie wykonania kontroli, a następnie odesłać wynik.

Z jakim typem serwera próbujesz się komunikować? Może być konieczne napisanie małej usługi, aby odpowiedzieć na żądanie.

MadcapLaugher
źródło
0

To nie dotyczy pytania PO, ale dla każdego, kto zwraca wyniki z bazy danych: oto prosta metoda, której użyłem.

Jeśli użytkownik nie załadował awatara, avatarpole byłoby NULL, więc wstawiłbym domyślny obraz awatara z imgkatalogu.

function getAvatar(avatar) {
    if(avatar == null) {
        return '/img/avatar.jpg';
    } else {
        return '/avi/' + avatar;
    }
}

następnie

<img src="' + getAvatar(data.user.avatar) + '" alt="">
timgavin
źródło
0

Działa dla mnie, użyj iframe, aby zignorować przeglądarki wyświetlające komunikat o błędzie GET

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

Chciałem funkcji, która zwróciłaby wartość logiczną, napotkałem problemy związane z zamknięciem i asynchronicznością. Rozwiązałem w ten sposób:

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);
},
Gianlorenzo Lenza
źródło