判斷瀏覽器是否支持 webp 的幾種解決方法

我們都知道,WebP 是 Google 推出的 WebP 圖片格式,它是一種支持有損壓縮和無損壓縮的圖片文件格式,根據Google測試,相同的圖片,WebP 格式的圖片均能比 PNG,JPG 格式的圖片節約不少體積,但是其兼容性不是很好,如下:

因此我們需要做一些兼容處理,那麼如何判斷瀏覽器支持 webp 呢?下面有幾種方法可供參考。

方法一

使用 canvas 的 toDataURL 進行判斷

toDataURL方法在MDN解釋如下:

HTMLCanvasElement.toDataURL() 方法返回一個包含圖片展示的 data URI 。可以使用 type 參數其類型,默認爲 PNG 格式。圖片的分辨率爲96dpi。
  • 如果畫布的高度或寬度是0,那麼會返回字符串“data:,”。
  • 如果傳入的類型非“image/png”,但是返回的值以“data:image/png”開頭,那麼該傳入的類型是不支持的。
  • Chrome支持“image/webp”類型。

toDataURL方法將圖片轉化爲包含dataURI的DOMString,通過 base64 編碼前面的圖片類型值是image/webp進行判斷。

比如在谷歌瀏覽器使用toDataURL方法轉成image/webp:

在 Safari 瀏覽器使用toDataURL方法轉成image/webp:

可以發現在不支持 webp 的瀏覽器進行toDataURL,得到的圖片類型並不是 webp,因此我們可以通過這個進行判斷。

實現方法:

var isSupportWebp = function () {
  try {
    return document.createElement('canvas').toDataURL('image/webp', 0.5).indexOf('data:image/webp') === 0;
  } catch(err) {
    return false;
  }
}

isSupportWebp()

方法二

在服務端根據請求header信息判斷瀏覽器是否支持webp

谷歌瀏覽器上請求圖片 header是這樣的:

IE 瀏覽器請求圖片 header是這樣的:

在圖片請求發出的時候,Request Headers 裏有 Accept,服務端可以根據Accept 裏面是否有 image/webp 進行判斷。

方法三

通過加載一張 webp 圖片進行判斷

const supportsWebp = ({ createImageBitmap, Image }) => {
  if (!createImageBitmap || !Image) return Promise.resolve(false);

  return new Promise(resolve => {
      const image = new Image();
      image.onload = () => {
          createImageBitmap(image)
              .then(() => {
                  resolve(true);
              })
              .catch(() => {
                  resolve(false);
              });
      };
      image.onerror = () => {
          resolve(false);
      };
      image.src = 'data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAAAAAAfQ//73v/+BiOh/AAA=';
  });
};

const webpIsSupported = () => {
  let memo = null;
  return () => {
      if (!memo) {
          memo = supportsWebp(window);
      }
      return memo;
  };
};

webpIsSupported()().then(res => {
    console.log("是否支持 webp", res)
}).catch(err => {
    console.log(err)
})

此方法會加載一張 1x1 的白色的正方形背景圖,用來測試瀏覽器是否支持 webp。

在 Google 測試代碼:

在 Firefox 測試代碼:

在 Safari 測試代碼:

Google官方文檔是這樣處理的(先加載一個WebP圖片,如果能獲取到圖片的寬度和高度,就說明是支持WebP的,反之則不支持):

function check_webp_feature(feature, callback) {
    var kTestImages = {
        lossy: "UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA",
        lossless: "UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==",
        alpha: "UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",
        animation: "UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA"
    };
    var img = new Image();
    img.onload = function () {
        var result = (img.width > 0) && (img.height > 0);
        callback(feature, result);
    };
    img.onerror = function () {
        callback(feature, false);
    };
    img.src = "data:image/webp;base64," + kTestImages[feature];
}

參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章