检测浏览器是不是支持WebP格式? (服务器端)

Posted

技术标签:

【中文标题】检测浏览器是不是支持WebP格式? (服务器端)【英文标题】:Detect if browser supports WebP format? (server side)检测浏览器是否支持WebP格式? (服务器端) 【发布时间】:2013-08-12 09:52:45 【问题描述】:

已经有一个关于Detecting WebP support 使用客户端的线程。如何使用服务器端检测 WebP 支持?

【问题讨论】:

这假设第一次加载页面时会加载.jpg,这违反了目的。 你可以从$_SERVER['HTTP_ACCEPT']中得到它吗? 看到这个帖子:***.com/questions/15165311/if-chrome-use-webp/… 【参考方案1】:

今天,您应该检查accept 标头中的image/webp。所有支持 WebP 的浏览器都会将此作为其接受字符串的一部分发送给所有请求(图像和非图像)。简而言之:

if( strpos( $_SERVER['HTTP_ACCEPT'], 'image/webp' ) !== false ) 
    // webp is supported!

(您可能想改用preg_match 并添加字边界检查和不区分大小写,但在现实世界中这应该没问题)


这是我几年前的原始答案,当时上述内容并不可靠

“正确”的方法是检查发送的 accept 标头,但 Chrome 中的一个错误意味着它不会列出 image/webp,即使它确实支持它。

这是一个相关的论坛帖子:https://groups.google.com/a/webmproject.org/forum/#!topic/webp-discuss/6nYUpcSAORs

链接到这个 bugtracker:https://code.google.com/p/chromium/issues/detail?id=169182 又链接到这个:https://code.google.com/p/chromium/issues/detail?id=267212

最终结果?虽然它还没有实现,但很快谷歌浏览器就会明确地将image/webp 列为图像非图像请求的可接受类型。因此,您提供 html 的脚本可以检查这一点。 Opera 已经将image/webp 作为其标准accept 标头的一部分发送(同样不管它是否是图像请求)。

所以,你可以这样检查:

if( strpos( $_SERVER['HTTP_ACCEPT'], 'image/webp' ) !== false || strpos( $_SERVER['HTTP_USER_AGENT'], ' Chrome/' ) !== false ) 
    // webp is supported!

(您可能想改用 preg_match 并添加字边界检查和不区分大小写,但在现实世界中这应该没问题。您可能还想检查至少版本 6 的 Chrome,但有很多没有人运行过时的版本,所以没有什么意义)

【讨论】:

有谁知道 Chrome 是否支持这个。最初的答案是在去年 8 月。 @Maelish 第一个错误跟踪器上的线程以“我现在也看到了 http 请求的图像/webp 标头”(日期为 2 月)结束,所以我猜是这样。好吧,最简单的检查方法就是尝试一下! Firefox 从 65 版开始支持 WebP 图片,但他们决定从 66 版开始将图片/webp 从 Accept 标头删除到主文档。 似乎 Firefox 再次在 Accept 中发送 image/webp。 注意!运行 Big Sur 的 Mac 上的 Safari 目前不会在接受标头中发送 image/webp。这就是我现在在 Safari 中接受标头的样子:Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8【参考方案2】:

戴夫的回答很好,但不适用于所有浏览器。我用这个方法:

function GetBrowserAgentName($user_agent) 
    if (strpos($user_agent, 'Opera') || strpos($user_agent, 'OPR/')) return 'Opera';
    elseif (strpos($user_agent, 'Edge')) return 'Edge';
    elseif (strpos($user_agent, 'Chrome')) return 'Chrome';
    elseif (strpos($user_agent, 'Safari')) return 'Safari';
    elseif (strpos($user_agent, 'Firefox')) return 'Firefox';
    elseif (strpos($user_agent, 'MSIE') || strpos($user_agent, 'Trident/7')) return 'Internet Explorer';
    return 'Other';

所以检查浏览器后:

  $BrowserAgentName = GetBrowserAgentName($_SERVER['HTTP_USER_AGENT']);
  If ($BrowserAgentName == 'Chrome' || $BrowserAgentName =='Opera') 
  // webp is supported!

  

这里我只是添加了 Opera 和 Chrome,您可以针对浏览器版本使用更深的检测器,并为您的 if 添加更多代理。但是您需要在浏览器更新以支持 image/webp 时更新此代码。

【讨论】:

您应该避免通过检查浏览器来检查功能;这导致了必须手动维护的脆弱代码(也是当前浏览器发送的极其复杂且自相矛盾的用户代理标头背后的主要原因)。这就是为什么我建议通过在接受标头中查找“image/webp”来直接检查该功能。所有支持 webp 的浏览器都会列出这个。进行浏览器检查的唯一原因是临时解决一个特定的、已知的(理想情况下是报告的)错误,就像我原来的答案一样。【参考方案3】:

我注意到 Facebook 的一件小事 - 他们的 facebookexternalhit 机器人(当有人向其发布地址时抓取您的网站的机器人)尚不能识别 webp 图像。 因此,我添加了以下检查,以在我的客户网站中为 Facebook 机器人禁用 webp 图像:

if (strstr(strtolower($_SERVER["HTTP_USER_AGENT"]), "facebook"))
    return false;

否则,当一个网页被分享时,它会显示错误的图像(它会在页面中找到的第一个 JPG)。

【讨论】:

【参考方案4】:

就我而言,我使用的是 C# Asp.Net MVC。 SO 没有指定技术,所以我发现自己在看这个线程。对于碰巧遇到这种情况的其他人来说,这是我想出的解决方案:

bool acceptsWebP = Request.AcceptTypes.Contains("image/webp");
string ext = Path.GetExtension(image.ImagePath);
string webP = image.ImagePath.Replace(ext, ".webp");
if (acceptsWebP)

    <img class="img-fluid lazy" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" data-src="\Uploads\@webP" >

else

    <img class="img-fluid lazy" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" data-src="\Uploads\@image.ImagePath" >

【讨论】:

以上是关于检测浏览器是不是支持WebP格式? (服务器端)的主要内容,如果未能解决你的问题,请参考以下文章

好评!Edge浏览器支持Chrome主推的.webp图片格式了

windows下查看webp格式图片

.dpg和.webp的图片格式

web项目性能优化(整理)

FirefoxEdge均将支持WebP图片格式(该格式来自Google)

三缺一就等 Safari 了:Firefox 宣布支持谷歌的 WebP 图片格式