解决 Converter for Media 不生效:宝塔面板 Nginx 伪静态配置指南

Converter for Media是WordPress平台一款热门的将图片免费转换为webp格式的插件,默认情况我们使用宝塔面板建站时服务器软件都是选择的nginx,这个情况下,需要手动配置nginx的配置来让Converter for Media正常工作。新手可能看不懂官方的文档,所以本文教大家在宝塔面板修改网站的nginx配置文件以保证Converter for Media的正常工作。

1、打开宝塔面板的网站设置界面

在宝塔面板的网站列表里面,选择你需要配置的网站,切换到配置文件界面,把默认内容先复制一份到本地保存备用。

解决 Converter for Media 不生效:宝塔面板 Nginx 伪静态配置指南-极客智库

2、修改配置文件

需要添加的代码

# BEGIN Converter for Media
    set $ext_avif ".avif";
    if ($http_accept !~* "image/avif") {
        set $ext_avif "";
    }
    
    set $ext_webp ".webp";
    if ($http_accept !~* "image/webp") {
        set $ext_webp "";
    }
    
    location ~* ^/wp-content/(?<path>.+)\.(?<ext>jpe?g|png|gif|webp)$ {
        add_header Vary Accept;
        add_header Cache-Control "private";
        expires 365d;
        try_files
            /wp-content/uploads-webpc/$path.$ext$ext_avif
            /wp-content/uploads-webpc/$path.$ext$ext_webp
            $uri =404;
    }
    # END Converter for Media

添加到准确的位置

Converter for Media的配置文件需要添加到对应的位置才能确保正常工作。具体的位置要求如下:

  • server { ... }块内
  • 在其他location { ... }指令之前
  • 在所有include指令之前

你可以参考上面的截图信息,大概在14行之后添加。

修改现有图片处理规则

找到原配置文件下面的内容:

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
    expires      30d;
    error_log /dev/null;
    access_log /dev/null;
}

修改为下面的内容:

location ~ .*\.(bmp|swf)$
{
    expires      30d;
    error_log /dev/null;
    access_log /dev/null;
}

然后点击保存,没有报错则证明修改准确。

3、测试插件是否正常工作

完成上面的配置修改后,只要宝塔面板没有报错,插件就应该可以正常工作了,你这个时候可以回到插件设置界面看看是否还有需要配置的提示,如果没有了提示并且你可以正常设置插件的选项或者批量处理之前的图片。那么就证明插件正常工作了。

4、如何检测图片是否变成了webp格式

你从网站前台查看图片地址或者保存图片,都是之前的格式,并没有变成webp,这种情况是正常的,插件作者专门发文解释了原因:该插件不会更改图片的URL,因此在查看网站源代码时,您将始终看到默认图片的URL。插件会创建重定向以输出WebP和AVIF格式的文件,更改这些图片的MIME类型,但不会更改URL。

插件的工作流程如下:

浏览器请求: GET /wp-content/uploads/photo.jpg
↓
插件检测浏览器支持WebP格式
↓
服务器内部重定向到: /wp-content/uploads-webpc/photo.jpg.webp
↓
浏览器收到WebP格式图片,但地址栏仍显示photo.jpg

这种设计的优势

  • SEO友好:URL结构保持不变,不影响搜索引擎优化
  • 兼容性:不支持新格式的老浏览器仍能收到原始格式图片
  • 无侵入性:不需要修改主题模板或页面内容
  • 自动化:用户无感知,完全后台自动处理

如何验证:

要确认插件是否正常工作,不要查看网页源代码,而是:

  1. 浏览器开发者工具(鼠标右键或者快捷键F12) → 网络(Network)标签
  2. 刷新页面查看图片请求
  3. 检查响应头中的Content-Type字段
  4. 应该看到image/webpimage/avif而不是image/jpeg

解决 Converter for Media 不生效:宝塔面板 Nginx 伪静态配置指南-极客智库

当你发现某张图还是老格式,证明转换后的图比原图大,所以插件抛弃了那张图的处理。

使用Cloudflare CDN发现图片没转换成功?

如果你使用的Cloudflare免费CDN,那么查看源代码返现还是原始的jpg或者png图片,并没有输出webp格式的图,这是因为插件需要借助浏览器的Accept 判断返回 WebP 还是 AVIF,这个功能免费版Cloudflare不支持,而Converter for Media默认也不会改变图片的url,所以CF那边识别到的就是 yuantu.jpg

我们要做的就是让图片支持变为 yuantu.jpg.webp 这样cf就会同时缓存jpg和webp两个图,将下面的代码添加到你主题函数文件。

/**
 * WordPress + Cloudflare Free + Converter for Media
 * 仅在 WebP 文件真实存在时,将 jpg/png 图片包装为 picture。
 * 支持 uploads 目录 + 当前主题目录图片。
 */

function nbj_get_webp_info($src, $uploads) {
    $src_raw  = html_entity_decode($src);
    $src_path = parse_url(esc_url_raw($src_raw), PHP_URL_PATH);

    if (!$src_path || strpos($src_path, '..') !== false) {
        return false;
    }

    /**
     * 1. 处理媒体库 uploads 图片
     */
    $uploads_baseurl = $uploads['baseurl'];
    $uploads_basedir = $uploads['basedir'];

    $uploads_base_path = parse_url(esc_url_raw($uploads_baseurl), PHP_URL_PATH);

    if ($uploads_base_path && strpos($src_path, $uploads_base_path . '/') === 0) {
        $relative = ltrim(substr($src_path, strlen($uploads_base_path)), '/');

        if (!$relative) {
            return false;
        }

        $webp_url  = str_replace('/wp-content/uploads/', '/wp-content/uploads-webpc/uploads/', $src_raw) . '.webp';
        $webp_path = dirname($uploads_basedir) . '/uploads-webpc/uploads/' . $relative . '.webp';

        return [
            'url'  => $webp_url,
            'path' => $webp_path,
        ];
    }

    /**
     * 2. 处理当前主题目录图片
     * 规则:/wp-content/themes/your-theme/xxx.jpg
     * 对应:/wp-content/themes/your-theme/xxx.jpg.webp
     */
    $theme_baseurl = get_stylesheet_directory_uri();
    $theme_basedir = get_stylesheet_directory();

    $theme_base_path = parse_url(esc_url_raw($theme_baseurl), PHP_URL_PATH);

    if ($theme_base_path && strpos($src_path, $theme_base_path . '/') === 0) {
        $relative = ltrim(substr($src_path, strlen($theme_base_path)), '/');

        if (!$relative) {
            return false;
        }

        $webp_url  = $src_raw . '.webp';
        $webp_path = rtrim($theme_basedir, '/') . '/' . $relative . '.webp';

        return [
            'url'  => $webp_url,
            'path' => $webp_path,
        ];
    }

    return false;
}

function nbj_wrap_webp_picture($content) {
    if (is_admin() || is_feed() || (defined('REST_REQUEST') && REST_REQUEST)) {
        return $content;
    }

    if (stripos($content, '<img') === false) {
        return $content;
    }

    $uploads = wp_upload_dir();

    // 支持 jpg/png,以及 jpg/png 后面带 query string 的情况
    $pattern = '/<img\b[^>]*\bsrc=(["\'])([^"\']+\.(?:jpe?g|png)(?:\?[^"\']*)?)\1[^>]*>/i';

    return preg_replace_callback($pattern, function ($m) use ($uploads) {
        $img_tag = $m[0];
        $src     = html_entity_decode($m[2]);

        if (
            strpos($img_tag, 'data-nbj-webp') !== false ||
            strpos($src, 'uploads-webpc') !== false ||
            strpos($src, '.webp') !== false
        ) {
            return $img_tag;
        }

        $webp = nbj_get_webp_info($src, $uploads);

        if (!$webp || !is_file($webp['path'])) {
            return $img_tag;
        }

        $img_tag = preg_replace('/<img\b/i', '<img data-nbj-webp="1"', $img_tag, 1);

        return '<picture data-nbj-webp="1">'
            . '<source srcset="' . esc_url($webp['url']) . '" type="image/webp">'
            . $img_tag
            . '</picture>';
    }, $content);
}

add_filter('the_content', 'nbj_wrap_webp_picture', 999);
add_filter('widget_text_content', 'nbj_wrap_webp_picture', 999);

add_action('template_redirect', function () {
    if (
        !is_admin()
        && !is_feed()
        && !(defined('REST_REQUEST') && REST_REQUEST)
        && ob_get_level() === 0
    ) {
        ob_start('nbj_wrap_webp_picture');
    }
});

原创文章,作者:极客智库终身会员,如若转载,请注明出处:https://www.jikezhiku.com/692.html

上一篇 6天前
下一篇 3天前

相关推荐