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


Detect if browser supports WebP format? (server side)

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

今天,您应该检查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/#!主题/web讨论/6nYUpcSAORs

链接到此错误跟踪器: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,并添加单词边界检查和不区分大小写,但在现实世界中,这应该没问题。你可能还想检查Chrome的至少版本6,但几乎没有人运行过时的版本,所以没有太多意义)

Dave的回答很好,但并非适用于所有浏览器。我使用这种方法:

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/web,您需要更新此代码。

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

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

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

在我的案例中,我使用的是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" alt="@item.ProductName">
}
else
{
    <img class="img-fluid lazy" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" data-src="'Uploads'@image.ImagePath" alt="@item.ProductName">
}