使用JavaScript检查服务器上是否存在图像?


124

使用javascript有没有办法判断服务器上资源是否可用?例如我有图像1.jpg-5.jpg加载到html页面中。我想每分钟或每分钟调用一次JavaScript函数,以便大致执行以下临时代码...

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

有什么想法吗?谢谢!

Answers:


208

您可以使用类似:

function imageExists(image_url){

    var http = new XMLHttpRequest();

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

    return http.status != 404;

}

显然,您可以使用jQuery / like执行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 2015年

9
除非CORS规则允许访问资源,否则这将失败。使用Image对象不会受到该限制。这样做的唯一好处是它实际上不会下载图像。
Alnitak

8
跨域问题。
阿米特·库玛

2
这确实有效,但是请记住,处理请求需要更长的时间,而且不是最佳解决方案。另外,它在跨原点上(在chrome中一定不能使用)不起作用,因此您不能在file:///协议上使用它,这意味着没有本地用法。
卡梅伦

117

您可以使用图像预加载器的基本工作方式来测试图像是否存在。

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

2
对于将来对此解决方案有疑问的Google员工,请尝试将img.src定义移到新的Image行之后。
加文

52

您可以通过使用为所有图像提供的内置事件来检查图像是否加载。

onloadonerror事件将告诉你,如果图像成功加载或发生错误后:

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替代方法的性能。这个答案的执行速度更快!
Samuel

我喜欢这种解决方案,无论如何,它都会在两种情况下都引入事件(异步执行),这在某些情况下可能会引起问题:我建议在任何情况下都添加映像,然后仅在出现错误时才替换它。
Giorgio Tempesta,

@adeno,当状态代码:404未找到时可以工作

@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

如果网址不存在,它将在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

不幸的是,如果我要检查有效的背景图片,那对我不起作用。background-image: url('/a/broken/url')给我200ok(Chrome 74)。
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请求并加载图像)。
昆汀
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.