JavaScriptを使用してサーバーに画像が存在するかどうかを確認しますか?


124

javascriptを使用して、サーバーでリソースが使用可能かどうかを確認する方法はありますか?たとえば、htmlページに読み込まれた画像1.jpg-5.jpgがあります。私は毎分JavaScript関数を呼び出したいと思います、それで大体次のスクラッチコードを実行します...

if "../imgs/6.jpg" exists:
    var nImg = document.createElement("img6");
    nImg.src = "../imgs/6.jpg";

考え?ありがとう!

回答:


208

あなたは次のようなものを使うことができます:

function imageExists(image_url){

    var http = new XMLHttpRequest();

    http.open('HEAD', image_url, false);
    http.send();

    return http.status != 404;

}

もちろん、jQuery / similarを使用してHTTPリクエストを実行できます。

$.get(image_url)
    .done(function() { 
        // Do something now you know the image exists.

    }).fail(function() { 
        // Image doesn't exist - do something else.

    })

4
ただし、関数名はfileExistsにしないでください。これは.js .css .htmlまたは他の公開されているファイルで機能します。
CoR、2015年

1
機能は最高です。私はそれを私のコレクションに入れました:) fileExistsこの関数は画像がサーバーに存在するかどうかをチェックしないので、私はもっといい名前だと思いました。サーバーからファイルにアクセスできるかどうかを確認します。そのファイルが実際に画像であるかどうかのチェックはありません。.pdf、.html、ランダムファイルの名前が* .jpgまたは* .pngに変更された可能性があります。何かが.jpgで終わっていても、それが100%画像であることを意味するわけではありません:)
CoR

9
CORSルールでリソースへのアクセスが許可されていない限り、これは失敗します。Imageオブジェクトを使用しても、その制限はありません。これの唯一の利点は、実際にイメージをダウンロードしないことです。
アルニタク2016

8
クロスドメインの問題。
Amit Kumar

2
これは機能しますが、リクエストの処理に時間がかかり、最善の解決策ではないことに注意してください。また、クロスオリジン(間違いなくchrome内)では機能しないため、file:///プロトコルでは使用できません。つまり、ローカルでの使用はありません。
キャメロン

118

イメージプリローダーが機能する基本的な方法を使用して、イメージが存在するかどうかをテストできます。

function checkImage(imageSrc, good, bad) {
    var img = new Image();
    img.onload = good; 
    img.onerror = bad;
    img.src = imageSrc;
}

checkImage("foo.gif", function(){ alert("good"); }, function(){ alert("bad"); } );

JSFiddle


ちょっとクールな機能!余談ですが、これは結果を匿名関数に直接返す興味深い方法です。私は通常、return@ ajtrichardsが彼の回答の最初の部分で持っているようなステートメントでこれを行います。
Sablefoste

絶対に; しかし、私は反対の方法が同期的であることを本当に考えたことはありません。私は手続き型コーディングの長い歴史から来ており、時々「他の」見方を見逃している...私は私だけではないと思います。;-)
Sablefoste 2017年

2
この解決策で問題が発生する今後のGoogle社員のために、img.src定義を新しいImage行の直後に移動してみてください。
Gavin

52

すべての画像に提供されている組み込みイベントを使用して、画像が読み込まれるかどうかを確認できます。

onloadそしてonerror、画像が正常にロードされた場合、またはエラーが発生した場合、イベントを教えてくれます。

var image = new Image();

image.onload = function() {
    // image exists and is loaded
    document.body.appendChild(image);
}
image.onerror = function() {
    // image did not load

    var err = new Image();
    err.src = '/error.png';

    document.body.appendChild(err);
}

image.src = "../imgs/6.jpg";

2
あらゆる場合に機能するため、私にとっては最良の答えです(接続の問題、外部サーバー...)+1
Reign.85

2
この回答のパフォーマンスをAJAX.get代替と比較しました。この答えははるかに速く実行されます!
サミュエル

私はこのソリューションが好きですが、どちらの場合にもイベントが発生し(非同期実行)、状況によっては問題が発生する可能性があります。どのような場合でも画像を追加し、エラーの場合のみそれを置き換えることをお勧めします。
ジョルジョテンペスタ

@adeno、ステータスコード:404が見つからない場合に機能しますか
-ManZ

@Mahi-404ページが実際に有効な画像を返さない限り、ステータスコードは問題になりませんerror。失敗すると、ハンドラーがトリガーされます。
adeneo

15

Reactベースのクライアントでこれを行うために誰かがこのページにアクセスした場合、以下のようなことができます。これは、ReactチームのSophia Alpertによって提供されたオリジナルの回答です。

getInitialState: function(event) {
    return {image: "http://example.com/primary_image.jpg"};
},
handleError: function(event) {
    this.setState({image: "http://example.com/failover_image.jpg"});
},
render: function() {
    return (
        <img onError={this.handleError} src={src} />;
    );
}

7

より優れた最新のアプローチは、ES6 Fetch APIを使用して画像が存在するかどうかを確認することです。

fetch('https://via.placeholder.com/150', { method: 'HEAD' })
    .then(res => {
        if (res.ok) {
            console.log('Image exists.');
        } else {
            console.log('Image does not exist.');
        }
    }).catch(err => console.log('Error:', err));

同じ発信元のリクエストを行っているか、サーバーでCORSが有効になっていることを確認してください。


6

イメージタグを作成してDOMに追加すると、そのonloadイベントまたはonerrorイベントが発生します。onerrorが発生した場合、画像はサーバー上に存在しません。


3

このJS関数を呼び出して、サーバーにファイルが存在するかどうかを確認できます。

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;
    }
}

1
良い努力。しかし、単一のフォームで複数の画像をロードするときに少し時間がかかります。
Nuwan Withanage

URLが存在しない場合、xhr.send()でエラーが表示されます。
Avinash Sharma

3

基本的には、約束されたバージョンの@espascarelloと@adeneoの回答と、フォールバックパラメータ:

const getImageOrFallback = (path, fallback) => {
  return new Promise(resolve => {
    const img = new Image();
    img.src = path;
    img.onload = () => resolve(path);
    img.onerror = () => resolve(fallback);
  });
};

// Usage:

const link = getImageOrFallback(
  'https://www.fillmurray.com/640/360',
  'https://via.placeholder.com/150'
  ).then(result => console.log(result) || result)

// It can be also implemented using the async / await API.

注:個人的にはこのfetchソリューションの方が好きかもしれませんが、欠点があります。サーバーが特定の方法で構成されている場合、ファイルが存在しなくても200/304を返す可能性があります。一方、これは仕事をします。


2
以下のためにfetch、あなたが使用できるokのプロパティresponse:オブジェクトを要求が成功したかどうかをチェックする fetch(url).then(res => {if(res.ok){ /*exist*/} else {/*not exist*/}});
attacomsian

残念ながら、有効な背景画像を確認したい場合は、うまくいきません。と(Chrome 74)background-image: url('/a/broken/url')をくれます。200ok
HynekS、

2

対応する画像フォルダへの相対パスを設定することにより、axiosでこれを行うことができます。私はjsonファイルを取得するためにこれを行いました。あなたは画像ファイルに対して同じ方法を試すことができます、あなたはこれらの例を参照するかもしれません

baseurlを使用してaxiosインスタンスを別のドメインのサーバーとして既に設定している場合は、Webアプリケーションをデプロイする静的ファイルサーバーの絶対パスを使用する必要があります。

  axios.get('http://localhost:3000/assets/samplepic.png').then((response) => {
            console.log(response)
        }).catch((error) => {
            console.log(error)
        })

画像が見つかった場合、応答は200になり、見つからない場合、応答は404になります。

また、画像ファイルがsrc内のassetsフォルダにある場合は、requireを実行してパスを取得し、そのパスを使用して上記の呼び出しを実行できます。

var SampleImagePath = require('./assets/samplepic.png');
axios.get(SampleImagePath).then(...)

0

これはうまくいきます:

function checkImage(imageSrc) {
    var img = new Image();        
    try {
        img.src = imageSrc;
        return true;
    } catch(err) {
        return false;
    }    
}

12
これが毎回trueに戻ることを確認してください。
Brandon McAlees

-3

このリンクを参照し、JavaScriptで画像ファイルが存在するかどうかを確認できます。

checkImageExist.js:

    var image = new Image();
    var url_image = './ImageFolder/' + variable + '.jpg';
    image.src = url_image;
    if (image.width == 0) {
       return `<img src='./ImageFolder/defaultImage.jpg'>`;
    } else {
       return `<img src='./ImageFolder/`+variable+`.jpg'`;
    } } ```

1
私はこれをテストしました。動作しません。常にデフォルトの画像を返します。(おそらく、ブラウザがHTTPリクエストを行って画像の幅をテストする前に画像をロードする時間がないためです)。
クエンティン、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.