最近琢磨着将静态资源链接的默认驿站域名替换成白嫖的国内备案域名方才接触到这个Module。具体参见:https://post.cplus8.com/d/608
对于替换网页内容,nginx官方自带的ngx_http_sub已经能够做到了,但对于我这种情况是无能为力的。如果我无脑将静态资源路径post.cplus8.com/assets替换成srimg.xpls.top的话就会把css的也换掉,出现RocketLoader兼容性问题;如果逐条替换那真是闲的蛋疼……
模块介绍
ngx_http_sub_module也仅是支持了最基本的字符串替换以及限定MINE类型sub_filter_tpyes(如text/html)和是否多次替换(sub_filter_once)的简单特性。而相比之下,有
由国人开发的ngx_http_substitutions_filter_module则显得极为强大,轻而易举的帮助我们解决上述问题。
项目地址:https://github.com/yaoweibin/ngx_http_substitutions_filter_module
先来看一下它的特性
一个使用示例
location / {
subs_filter_types text/html text/css text/xml;
subs_filter st(\d*).example.com $1.example.com ir;
subs_filter a.example.com s.example.com;
subs_filter http://$host https://$host;
}
下文将简单介绍如何安装和使用
Details of installation and usage are as follows.
安装/Installation
由于是第三方非内置的模块,这里需要你重新编译您的nginx。
如果您在用宝塔面板,您可以下滑
- 下载ngx_http_substitutions_filter_module源码
cd /path/to/ngx_http_substitutions_filter_module
git clone https://github.com/yaoweibin/ngx_http_substitutions_filter_module.git
2.使用nginx -V查看现在的编译参数
root@cpluserver:~# nginx -V
nginx version: nginx/1.23.2
built by gcc 10.2.1 20210110 (Debian 10.2.1-6)
built with OpenSSL 1.1.1q 5 Jul 2022
TLS SNI support enabled
configure arguments: --user=www --group=www --prefix=/www/server/nginx --add-module=/www/server/nginx/src/ngx_cache_purge --with-openssl=/www/server/nginx/src/openssl --with-pcre=pcre-8.43 --with-http_v2_module --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module --with-http_stub_status_module --with-http_ssl_module --with-http_image_filter_module --with-http_gzip_static_module --with-http_gunzip_module --with-ipv6 --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-ld-opt=-Wl,-E --with-cc-opt=-Wno-error --with-ld-opt=-ljemalloc --with-http_dav_module --add-module=/www/server/nginx/src/nginx-dav-ext-module
将configure arguments后面一串编译参数复制出来备用
3.下载nginx源码进行编译,替换原来的nginx
cd /opt/nginx-1.24.0
wget https://nginx.org/download/nginx-1.24.0.tar.gz
tar -xvf nginx-1.24.0.tar.gz
cd nginx-1.24.0.tar.gz
./configure [原有参数] --add-module:/path/to/ngx_http_substitutions_filter_module
make
cd /usr/local/nginx/sbin
mv ./nginx ./nginx.bak #备份原有nginx
mv /opt/nginx-1.24.0/nginx ./ #将编译好的nginx移到这里
/usr/local/nginx/sbin/nginx #n↘ginx↗,启动~
nginx -V #查看模块是否添加成功
Especially
如果您使用的是宝塔面板的话,在最近的安装的脚本当中,他们已经默认加入了ngx_http_substitutions_filter_module模块,(这一点我还是吹吹宝塔)您可以通过nginx -V来确认是否存在;若无,您只需要将原有版本卸载再安装一遍即可以;如果还是不行,您可以在安装时选择编译安装并且添加好这模块的参数--add-module:/path/to/ngx_http_substitutions_filter_module完成安装。
别问为什么我在安装时看到有报错提示:ngx_http_substitutions_filter_module have multiple definitions时困惑了很久。
至此,您的nginx已经具备高级的内容替换了!
说明和使用范例/Usage & Examples
以下是说明:
Directives
* subs_filter_types
* subs_filter
subs_filter_types
syntax: *subs_filter_types mime-type [mime-types] *
default: *subs_filter_types text/html*
context: *http, server, location*
*subs_filter_types* is used to specify which content types should be
checked for *subs_filter*, in addition to *text/html*. The default is
only *text/html*.
This module just works with plain text. If the response is compressed,
it can't uncompress the response and will ignore this response. This
module can be compatible with gzip filter module. But it will not work
with proxy compressed response. You can disable the compressed response
like this:
proxy_set_header Accept-Encoding "";
subs_filter
syntax: *subs_filter source_str destination_str [gior] *
default: *none*
context: *http, server, location*
*subs_filter* allows replacing source string(regular expression or
fixed) in the nginx response with destination string. The variables
in matching text is only avaiable under fixed string mode, which means
the matching text could not contain variables if it is a regular
expression. Substitution text may contain variables. More than one
substitution rules per location is supported.
The meaning of the third flags are:
* *g*(default): Replace all the match strings.
* *i*: Perform a case-insensitive match.
* *o*: Just replace the first one.
* *r*: The pattern is treated as a regular expression, default is
fixed string.
subs_filter_bypass
syntax: *subs_filter_bypass $variable1 ...*
default: *none*
context: *http, server, location*
You can specify several variables with this directive. If at least one
of the variable is not empty and is not equal to '0', this substitution
filter will be disabled.
你可以看到,这玩意指令叫subs_filter真就对标ngx_http_sub_module的sub_filter。
这里简单说明下:
subs_filter_type [MINE] ,需要设置proxy_set_header Accept-Encoding "";禁用gzip压缩与前者一样,这里不必赘述。
subs_filter允许将nginx响应中的源字符串(正则表达式或固定的)和目标字符串。变量
只有在固定字符串模式下,匹配文本中的变量才是可用的,这意味着 匹配的文本不能包含变量,如果它是一个正则表达式。替换文本可以包含变量。支持每个位置有一个以上的变量。支持每个位置有多个替换规则。
subs_filter [source_str] [destination_str] 参数(igor)
参数说明
g(默认):替换匹配项。
i :区分大小写的匹配
o : 只匹配发现的第一个。
r : 启用正则匹配。
subs_filter_bypass 变量1 变量2 …
示例
对于驿站的需求,相比您已经很快就能想出来的。
我们可以使用正则对特定的文件后缀进行匹配
,从而完成替换,像这样
subs_filter https://post.cplus8.com/assets/([^"\']*?)\.(jpg|png|webp|js|jpeg|bmp|woff2|woff) https://post.cplus8.com/assets/$1.$2 igr;
变量一包含了任意字符,变量2包含了特定的文件后缀,这样便可以替换css之外一些常用的静态资源到国内cdn。然而这也并非什么优雅的方法,最好还是去写个flarum插件修改,这只是个下下策。
其他实例
全站http资源替换成https
subs_filter http://$host https://$host;