使用 nginx sub_filter 多次替换相同的值

使用 nginx sub_filter 多次替换相同的值

编辑:可重现的示例: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 将要替换的键存储在哈希结构中,即替换xy

现在,当 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>";

相关内容