前言

在 daily coding 的时候经常会有这种需求:

if url 是图片,则 A;
else B.

那么,如何判断一个 url 是否是图片呢?

进入正题

正则

通过判断 url 的结尾扩展名:

function isImgUrl(url) {
  return /\.(jpg|jpeg|png|webp|avif|gif)$/.test(url);
}

诚然,这种方式只要枚举出所有的图片扩展名,就可以校验出是否是图片。

但是我们也经常会遇到一些图片,**_压根没有扩展名_**

比如我的 github 头像:https://avatars.githubusercontent.com/u/19246724?v=4

利用 <img> 的 onload 事件

将 url 赋值给 img 的 src 属性,如果可以出发 img 的 onload 方法,则 url 为图片。

但是,这种方法浏览器会下载整个图片,造成不必要的资源浪费。

发送 HEAD 请求只检查 MIME

发送 HEAD 请求,根据 response.headers 中的 Content-Type 来判断。

function isImgUrl(url) {
  return fetch(url, { method: "HEAD" }).then((res) => {
    return res.headers.get("Content-Type").startsWith("image");
  });
}

不同的图像都是以 image MIME 类型开头,比如 jpge 是 image/jpeg,png 是 image/png 等。
这样,不用担心响应请求的开销,就可以知道 url 是否是图片。

结尾

虽然这种通过校验 MIME 的方法可以校验是否是图片,但是由于发送请求的缘故,当 CORS 被拦截的时候,它就不灵了 😢