博客
Demo

需求背景

由于我们是saas服务 用户需要在自己的网站上添加特定的SEO信息 但是后台管理里配置动态meta是不生效的 原因在于爬虫只会搜索静态资源 并不会读取js加载后的内容 所以针对这个需求 我们整理了一些方案 在这里分享给大家

方案整理

针对这个问题整理了如下两个方案

  1. 前端打包后把资源上传到S3 然后在后台项目里出一个接口返回S3上的前端页面 这样的话可以读取后台配置里的条目去添加 优点是可以直接从后台配置比较灵活 缺点是要从后端改造 会侵入后端代码 而且用java去返回静态文件的话 服务端压力过大时也会对前端加载造成影响

  2. 第二个方案是查了一些资料后 确定可以通过直接修改nginx配置 针对不同的域名替换不同的SEO配置 优点是不需要侵入业务代码 改动成本低 缺点是没法通过后台配置 只能每次手动修改 需要重新打包web页面(这里重新打包是因为前端项目部署在docker里 虽然前端文件并没有更改 依然要走整个的ci/cd流程 但是由于前端代码没有变化 打包后的文件哈希并不会变 不会让用户重新加载资源)

实施过程

经过一番讨论我们确定了方案二 因为SEO配置不会频繁改动 而且这种方式的实施成本很低 只需要前端改动下项目里的nginx配置即可 这里我们使用了nginx的sub_filter来进行了第一次尝试 (因为涉及到公司的一些内容 这里对域名和content进行了脱敏 大家替换成自己的域名和content即可)

server {
    listen 80 default_server;
    server_name _;
    root /bh/www ;
    index index.html index.htm;

    location / {
        if ($host ~ "new.xxx"){
            sub_filter '<head>' '<head><meta name="google-site-verification" content="xxx" />';
            sub_filter_once on;
        }
        if ($host ~ "xxxxxx"){
            sub_filter '<head>' '<head><meta name="google-site-verification" content="xxx" />';
            sub_filter_once on;
        }

        try_files $uri $uri/ /index.html;
    }

    location ^~ /static/ {
      gzip_static on;
      expires max;
      add_header Cache-Control public;
    }
    error_page 404 /index.html;
    client_max_body_size 20M;
}

    

sub_filter指令接受两个参数 第一个是要替换的字符串 第二个是替换后的字符串 我们更改成如上配置后进行了第一次尝试.发现nginx没有正常启动起来 报错是"sub_filter" directive is not allowed here 通过查询确定这个问题的原因image

这个意思是在http server location这几个规则中 sub_filter无法在其他指令下使用 意味着我们不能写在if里 于是我们这里使用了map来做一个映射 改造后配置如下

map $host $conditional_filter {
        ~xxx      '<head><meta name="google-site-verification" content="xxx" />';
        ~xxx.app   '<head><meta name="google-site-verification" content="xxx" />';
        ~xxxxxx  '<head><meta name="google-site-verification" content="xxx" />';
        default '<head><meta name="google-site-verification" content="xxx" />';
}
server {
    listen 80 default_server;
    server_name _;
    root /bh/www ;
    index index.html index.htm;

    location / {
        sub_filter "<head>" $conditional_filter;
        sub_filter_types *;
        sub_filter_once off;
        try_files $uri $uri/ /index.html;
    }

    location ^~ /static/ {
      gzip_static on;
      expires max;
      add_header Cache-Control public;
    }
    error_page 404 /index.html;
    client_max_body_size 20M;
}

再次提交部署后 部署流程走通 我们来看一下部署后的效果

image
image

针对不同的域名正确的返回了对应的meta信息 此时我们的需求就正常完成了 希望我的踩坑经历能对大家有所帮助

参考资料:

use-of-sub-filter-in-if-block-under-nginx-config
nginx_sub_module

Skelanimals Blog © 2026 Made By Skelanimals
冀公网安备 13098102000240号  冀ICP备17020251号-1