nginx sub_filter 无法处理某些未压缩的 json

问题描述 投票:0回答:1

我现在已经花了太多的时间/天来谷歌搜索这个问题,我几乎已经在chatgpt上寻求答案了,所以现在我需要征求一些意见。

我在 php-fpm 服务器(wordpress)前面有一个 nginx 反向代理。我正在使用 sub_filter 更改响应中的一些值。

这适用于某些 json 响应,但不适用于其他响应。

以下是 nginx.conf 的相关部分:

# Reverse proxy
server {
    ... # certificates, logging etc. removed for simplicity

    root /var/www/html;
    index index.php index.html index.htm;
    
    ...

    location / {
        gzip off;

        ... # proxy_set_header stuff removed

        proxy_set_header Accept-Encoding "";

        proxy_pass http://127.0.0.1:8082;

        sub_filter_once off;
        sub_filter_types *;
        sub_filter "target_vlue" "replacement_value";
    }
}

# Application http
server {
    ... # listen, logging etc removed

    location ~ \.php$ {
            gzip off;
            try_files $uri =404;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_index index.php;
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
            fastcgi_param PATH_INFO $fastcgi_path_info;

            fastcgi_pass test-wordpress:9000; #its docker
    }
}

我有双服务器设置,原因是 - 与此无关。

注意 gzip 关闭;和接受编码“”;

在 php-pfm 中,压缩被关闭:

9dedac8fdba4:/var/www/html# php -i |grep zlib zlib.output_compression => Off => Off zlib.output_compression_level => -1 => -1 zlib.output_handler => no value => no value
我检查了响应中的Content-Type标头是application/json; charset=utf-8 ,并且我检查了 application/json 是 sub_filter 类型配置的一部分。

进一步调试

sub_filter不起作用的json是由Wordpress(插件)生成的。它很大,但这里是一个片段:

{ "success": true, "data": { "responses": { "app_site_editor_template_types": { "success": true, "code": 200, "data": [ { "type": "header", ... "urls": { ... "thumbnail": "https://<TARGET_VALUE>/wp-content/plugins/elementor/assets/images/app/site-editor/header.svg", // <-- Here target_value is not changed by subfiler "EXTRA_DEBUG_TEST": "DEADBEEF" // <--- My test, also not changed } }, ...
正如评论所说,“TARGET_VALUE”并未如希望的那样被 sub_filter 更改。如果我更改 sub_filter 来替换“DEADBEEF”,那也不起作用。所以它不是价值本身。我已经编辑了插件 .php 以注入 json 的额外“EXTRA_DEBUG_TEST”部分。

如果我将此 JSON 的简单部分放入 .php 文件中并通过相同的服务器设置请求该文件,那么这些值将按预期替换:

{ "status": "success", "message": "This is a simple JSON response", "items": [ 1, 2, 3, 4, 5 ], "url": "https://<TARGET_VALUE>", // <-- sub_filter catches and changes this "url2": "https://<TARGET_VALUE>/wp-content/plugins/elementor/assets/images/app/site-editor/header.svg", // <-- sub_filter catches and changes this }
注意:第二个 json 是使用的整个 debug-json。

有人知道这里发生了什么事吗?

编辑:它不是 json。我编辑了插件 .php 以返回一个非常简单的 json 对象:

{ "success": true, "data": { "responses": [ "https://<TARGET_VALUE>/wp-admin" ] } }
sub_filter 仍然没有替换 target_value。

json wordpress nginx
1个回答
0
投票
好吧,我终于找到了问题所在。以防将来有人遇到同样的问题,我会将解决方案发布在这里。

Wordpress 插件是 Elementor 和 Elementor-pro。我的问题与主题编辑器功能特别相关。它是一个专业功能,它调用 admin-ajax.php 来获取一些编辑器配置值。触发的动作是:

$ajax->register_ajax_action( 'app_site_editor_template_types', [ $this, 'get_template_types' ] );
实现看起来没问题。但罪魁祸首是在 Elementor 核心中,特别是在 elementor/core/common/modules/ajax/module.php 中,我们有这个 gem:

private function send_success() { // things left out if ( function_exists( 'gzencode' ) ) { $response = gzencode( $json ); header( 'Content-Type: application/json; charset=utf-8' ); header( 'Content-Encoding: gzip' ); header( 'Content-Length: ' . strlen( $response ) ); echo $response; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } else { echo $json; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } wp_die( '', '', [ 'response' => null ] ); }
此函数包装了对 admin-ajax.php 的调用。正如我们所看到的,它很高兴地忽略任何 HTTP 标头和 PHP 配置,并无论如何压缩输出 JSON。这就是为什么 nginx 或 php 配置更改没有任何效果。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.