【问题标题】:How to get ALL 404 on images loading如何在图像加载时获得 ALL 404
【发布时间】:2020-07-18 18:43:15
【问题描述】:

问题:

我有一个从外部来源加载大量图像的网页。其中一些图像链接可能会被破坏,我有一个通过onerror 属性调用的脚本,如果它没有加载,它会删除图像(以及一些相关内容,如标题、一些标签......)。

在大多数情况下都可以,除非图像服务器向我发送默认图像来替换丢失的图像。在这种情况下,onerror 事件不会触发,并且我的页面会得到一个丑陋的默认图像。

我想做什么:

我希望能够检测并删除这些图像。

问题:

1) 有没有办法检测从 img 标签加载的图片的状态码(404)? (从我所做的研究来看,这似乎是不可能的,但我仍然在问......)。

2) 如果 #1 不可行,一种解决方案似乎是调用以 XMLHttpRequest 之类的内容加载图像并查看响应代码。在这种情况下:

  • 有没有比XMLHttpRequest更合适的方式?

  • 我应该预料到 CORS 会出现很多问题吗?

供参考,这里是基于XMLHttpRequest的解决方案草案:

function imgLoad(url, onOk, onProblem) {
    'use strict';

    var request = new XMLHttpRequest();
    request.open('GET', url);
    request.responseType = 'blob';

    request.onload = function () {
        if (request.status === 200) {

            onOk(request.response);

        } else {

            onProblem();

        }
    };

    request.onerror = function () {
        // if the request fails

        onProblem();
    };

    request.send();
};


function onOk(response) {

    var body = document.querySelector('body');
    var myImage = new Image();
    myImage.crossOrigin = ""; // or "anonymous"

    var imageURL = window.URL.createObjectURL(response);

    myImage.src = imageURL;
    body.appendChild(myImage);
};

function onProblem(err) {
    // remove the image and the other related elements
};

function loadImage(url) {
    'use strict';

    imgLoad(url, onOk, onProblem);
};

编辑:

回答@O.o,实际代码是这样的:

<img src="http://someimageurl.jpg" onerror="imgError(this);">

只是一个简单的 img 标签。 imgError 功能是在图像未加载时删除与图像相关的元素的功能。但是如果返回默认图像则不起作用,只有在返回NO图像时才起作用。

【问题讨论】:

  • 404 错误响应通常不会有 Access-Control-Allow-Origin 响应标头。这意味着您无法从前端 JavaScript 代码访问这些响应的任何属性。因此,如果外部服务器以缺少 Access-Control-Allow-Origin 响应标头的 404 响应,那么从您的前端代码中,您将无法检测到它是 404。您将能够检测是请求失败的请求。因此,如果您想以编程方式准确检测 404,则无法从前端代码中完成。您应该改为从后端代码执行此操作。
  • 为什么不分享当前代码?

标签: javascript html image cors http-status-code-404


【解决方案1】:

这是我实施的实际解决方案。同时我为图像添加了延迟加载。这是代码,以防它帮助任何人:


/**
* this function load the image using an XMLHttpRequest to be able to read the status code from javascript.
*/

function imgLoad(image, onOk, onError) {

    var url = image.dataset.src;

    var request = new XMLHttpRequest();
    request.open('GET', url);
    request.responseType = 'blob';

    request.onload = function () {
        if (request.status === 200) {

            onOk(request.response, image);
        } else {

            onError(image);
        }
    };

    request.onerror = function () {
        // if the request fails
        onError(image);
    };

    request.send();
};


/**
* This function is called if the image successfully loads. It just replace the "src" prop and the image is pulled from the cache from the browser.
*/

function onOk(response, image) {

    image.crossOrigin = ""; // or "anonymous"

    var imageURL = window.URL.createObjectURL(response);

    //image.src = imageURL;  // to use the blob response
    image.src = image.dataset.src;  // to use normal src and disk cache
    image.onerror = "";
    image.classList.remove("lazy");
};

/**
* small helper
*/
function loadImage(image) {

    imgLoad(image, onOk, imgError);
};


/**
* wrap up and lazy loading implementation
*/
document.addEventListener("DOMContentLoaded", function() {
    var lazyImages = [].slice.call(document.querySelectorAll("img.lazy"));

    if ("IntersectionObserver" in window) {
      let lazyImageObserver = new IntersectionObserver(function(entries, observer) {
        entries.forEach(function(entry) {
          if (entry.isIntersecting) {
            let lazyImage = entry.target;

            loadImage(lazyImage);

            lazyImageObserver.unobserve(lazyImage);
          }
        });
      });

      lazyImages.forEach(function(lazyImage) {
        lazyImageObserver.observe(lazyImage);
      });
    } else {
      // fall back
      lazyImages.forEach(function(lazyImage) {
        loadImage(lazyImage);
      });
    }
  });

我没有包含“onError”函数,因为它对我的代码非常具体,在这里并不特别相关。

【讨论】:

    猜你喜欢
    • 2020-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-28
    • 1970-01-01
    • 1970-01-01
    • 2010-12-06
    • 1970-01-01
    相关资源
    最近更新 更多