![使用 nginx sub_filter 多次替换相同的值](https://linux22.com/image/768123/%E4%BD%BF%E7%94%A8%20nginx%20sub_filter%20%E5%A4%9A%E6%AC%A1%E6%9B%BF%E6%8D%A2%E7%9B%B8%E5%90%8C%E7%9A%84%E5%80%BC.png)
编辑:可重现的示例:https://github.com/searchingforlife/nginx-substitution
我正在尝试向 HTML 文件/输出添加/注入任意数量的脚本。它们都根据相同的值进行过滤</body>
以注入自身。
nginx version: nginx/1.16.1
假设我们有两个像这样的 conf 文件(简化):
# script_one.conf
sub_filter "</body>" "<script src='/one.js'></script></body>";
# script_two.conf
sub_filter "</body>" "<script src='/two.js'></script></body>";
我们的主要 nginx 配置文件如下:
location /one {
sub_filter_once off;
include /script_one.conf;
include /script_two.conf;
}
但这似乎不起作用,nginx 只添加了第一个脚本。如果过滤器值不同(比如一个过滤为</head>
,另一个过滤为</body>
),则 nginx 会注入两个脚本。
有没有办法绕过这个限制并让 nginx 注入这两个脚本?我知道我可以创建一个新的 conf 文件,将两个脚本合并为一个并将其包含在内,但是当您有 10 多个脚本需要注入并且可以根据位置以各种方式组合时,这种方法无法扩展。
答案1
这是猜测,我还没有从 nginx 源代码中验证过。我假设 nginx 将要替换的键存储在哈希结构中,即替换x
为y
。
现在,当 nginx 按顺序读取配置文件时,它首先将一个键添加</body>
到替换映射中,然后用第二个键替换它。
答案2
我最终想到了一种不同的方法,只需重写一次。如果有人感兴趣,请参阅解决方案分支:https://github.com/searchingforlife/nginx-substitution/tree/solution
基本上,我们创建一个变量来保存要注入的脚本的名称,然后一次性注入它们。这样,我们最终只需要重写一次。
location ~ ^/ {
set $js_args "one,two";
include scripts.conf;
}
# scripts.conf
if ($js_args ~ "^$") {
set $js_args '';
}
set $scripts "";
if ($js_args ~* "(,|^)one([,]|$)") {
set $scripts "${scripts}<script src='/one.js'></script>";
}
if ($js_args ~* "(,|^)two([,]|$)") {
set $scripts "${scripts}<script src='/two.js'></script>";
}
sub_filter "</body>" "${scripts}</body>";