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

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


有什么想法?谢谢!

#1 楼

您可以使用类似以下内容的东西:

function imageExists(image_url){

    var http = new XMLHttpRequest();

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

    return http.status != 404;

}


显然,您可以使用jQuery /类似的代码来执行HTTP请求。

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

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

    })


评论


但函数名称不应为fileExists,因为它适用于.js .css .html或任何其他公共可用文件。

–CoR
2015年6月11日14:56

功能很棒。我把它放在我的收藏中:)我以为fileExists是更好的名称,因为此函数不检查服务器上是否存在映像。它检查是否可以从服务器访问文件。没有检查该文件是否实际上是图像。它可以是.pdf,.html,也可以是一些随机文件,重命名为* .jpg或* .png。如果某些内容以.jpg结尾,则并不意味着它是100%的图片:)

–CoR
15年6月16日在9:53

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

– Alnitak
16年7月13日在18:28



跨域问题。

–阿米特·库玛(Amit Kumar)
16年8月25日在10:41

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

–卡梅伦
17年5月20日在22:40

#2 楼

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

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

评论


嘿,很酷的功能!附带说明一下,这是一种直接返回匿名函数的返回结果的有趣方式。我通常会在他的回答的第一部分中使用@ajtrichards这样的return语句来执行此操作。

– Sablefoste
17年1月18日在20:44

绝对;但我从未真正想到过另一种同步方式。我来自过程编码的悠久历史,有时会错过看事物的“其他”方式……我敢打赌,我并不是唯一的人。 ;-)

– Sablefoste
17年1月18日在22:03

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

–加文
17年7月26日在8:36

如果图像服务器返回带有实际图像内容的404,例如,这会帮助捕获404错误。 YouTube缩略图服务可以:i3.ytimg.com/vi/vGc4mg5pul4/maxresdefault.jpg

–gvlasov
9月15日19:53



@gvlasov,如果是这种情况,则必须执行head请求并查看响应。从2013年的一个问题中可以选择一个...

–epascarello
9月15日20:07

#3 楼

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

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


评论


对我来说最好的答案,因为它在每种情况下都有效(连接问题,外部服务器...)+1

–统治85
2014-09-30 17:18

比较了此答案与AJAX.get替代方法的性能。这个答案的执行速度更快!

–塞缪尔
16年2月16日在19:38

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

–乔治·坦佩斯塔(Giorgio Tempesta)
18年1月31日在11:01

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

–马希
19年3月11日在8:03

@Mahi-状态代码无关紧要,只要404页实际上未返回有效图像,它将失败并触发错误处理程序。

– adeneo
19年3月21日在22:39

#4 楼

如果有人访问此页面希望在基于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} />;
    );
}


#5 楼

更好,更现代的方法是使用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已在服务器上启用。

评论


2020年最简单的方法。谢谢。

–纳达夫
9月9日9:11

这难以置信。这是什么时候出现的?

–凯尔·贝克(Kyle Baker)
11月4日19:27

@KyleBaker Fetch API可以使用很长时间了。现在,它已被所有现代浏览器广泛支持-约有95%。

– attacomsian
12月3日13:32

#6 楼

如果创建图像标签并将其添加到DOM,则应触发其onload或onerror事件。如果触发了onerror,则该映像在服务器上不存在。

#7 楼

基本上是@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不存在。另一方面,这将完成工作。

评论


对于抓取,您可以使用响应对象的ok属性检查请求是否成功:fetch(url).then(res => {if(res.ok){/ * exist * /}其他{/ *不存在*/}});

–attacomsian
19年5月18日在7:51



不幸的是,如果我想检查有效的背景图像,那对我不起作用。背景图片:url('/ a / broken / url')给我200并确定(Chrome 74)。

–HynekS
19年5月20日在10:22



#8 楼

您可以调用此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;
    }
}


评论


好功夫。但是以一种形式加载多个图像时会浪费一点时间。

–怒湾Withanage
18年11月14日9:00

如果网址不存在,它将在xhr.send()处显示错误。

– Avinash Sharma
19年9月6日在12:58

#9 楼

您可以通过将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文件夹中,则可以执行一个需求,获取路径,并使用该路径进行上述调用。

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


#10 楼

效果很好:

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


评论


可以肯定,每次都会返回true吗?

–布兰登·麦卡利斯(Brandon McAlees)
18年6月20日在14:52

#11 楼

如果您使用的是React,请尝试使用此自定义图片组件:
import React, { useRef } from 'react';
import PropTypes from 'prop-types';

import defaultErrorImage from 'assets/images/default-placeholder-image.png';

const Image = ({ src, alt, className, onErrorImage }) => {
  const imageEl = useRef(null);
  return (
    <img
      src={src}
      alt={alt}
      className={className}
      onError={() => {
        imageEl.current.src = onErrorImage;
      }}
      ref={imageEl}
    />
  );
};

Image.defaultProps = {
  onErrorImage: defaultErrorImage,
};

Image.propTypes = {
  src: PropTypes.string.isRequired,
  alt: PropTypes.string.isRequired,
  className: PropTypes.string.isRequired,
  onErrorImage: PropTypes.string,
};

export default Image;


#12 楼

您可以引用此链接来检查图像文件是否包含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'`;
    } } ```



评论


我刚刚测试过。没用它总是返回默认图像。 (可能是因为浏览器没有时间在尝试测试图像宽度之前发出HTTP请求并加载图像)。

–昆汀
19-10-25在6:37