繁体   English   中英

Nginx 在响应数据之前添加来自其缓冲区的发布请求正文内容?

[英]Nginx prepends response data with post request body content from its' buffer?

几天来,我在一个在ubuntu系统上的 docker 容器中运行并使用laravel/rebing-graphql供应商提供graphql查询响应的laravel应用程序中遇到了一个奇怪的问题。

所以我使用GraphiQL接口将 graphql 请求发送到我的后端。 我收到的请求结果不仅包括有效响应,还包括我与发布请求一起发送的参数;

"{\"query\":\"query Users {\\n  users(pagination: {offset: 0, limit: 1}) {\\n    items {\\n      id\\n    }\\n  }\\n}\",\"variables\":null,\"operationName\":\"Users\"}{\"data\":{\"users\":{\"items\":[{\"id\":53}]}}}"

此响应不带有 content-type: application/json而是text/html 似乎 post 请求正文已添加到我的 API 的响应数据中。 这会导致我的客户端出现 JSON 解析错误。 这里的 API 数据部分本身似乎是有效的。

这个问题最奇怪的是,它发生在每一(!)请求上。 因此,我大约 50% 的请求都收到了一个有效的响应,该响应确实以 json 格式出现,并且没有任何前置的 post 请求正文。

我试图分析此问题的根本原因,但我无法在代码中找到将参数作为附加输出回显的位置。

nginx 配置是否会导致发布请求正文内容的前置?

在我进一步调查期间,我开始替换 laravel 的公共目录中的index.php文件并创建了一个自定义index.php ,其中只包含一个exit("test") 执行 结果出乎意料。 我仍然在每个第二个请求的输出中附加了我的 post 参数:

"{\"query\":\"query Users {\\n  users(pagination: {offset: 0, limit: 1}) {\\n    items {\\n      id\\n    }\\n  }\\n}\",\"variables\":null,\"operationName\":\"Users\"}test"

我正在使用来自 nginx:alpine 和 php:7.4-fpm-alpine 的 docker 映像。 docker 容器打开一个端口,该端口从运行在我的根系统上的 apache2 服务器获取代理。

这是我的 nginx 默认配置:

server {
listen 80;

server_name my-domain.com;
error_log  /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;

root /var/www/html/public;

index index.php index.html;

location / {
    client_max_body_size 100M;

    if ($request_method = 'OPTIONS') {
        add_header Access-Control-Max-Age 1728000;
        add_header Access-Control-Allow-Credentials true;
        add_header Access-Control-Allow-Origin $http_origin;
        add_header Access-Control-Allow-Methods "GET, POST, OPTIONS, PUT, DELETE, HEAD";
        add_header Content-Length 0;
        add_header Content-Type "text/plain; charset=UTF-8";
        add_header Access-Control-Allow-Headers "Origin,X-Requested-With,Content-Type,Accept,X-CSRF-Token,X-XSRF-TOKEN,Authorization";
        return 204;
    }

    try_files $uri $uri/ /index.php?$query_string;
    gzip_static on;
}

location ~ \.php$ {
    client_max_body_size 100M;

    if ($http_origin ~* "^(blob:)?http(s)?://www.my-domain.com(:[0-9]{2,4})?$") {
        add_header Access-Control-Allow-Credentials true;
        add_header Access-Control-Allow-Origin $http_origin;
        add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
        add_header Access-Control-Allow-Headers "Origin,X-Requested-With,Content-Type,Accept,X-CSRF-Token,X-XSRF-TOKEN,Authorization";
    }

    try_files $uri =404;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass epapistagephp:9000;
    fastcgi_index index.php;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
} 
}

是否有人已经经历过这种行为,或者您是否暗示从哪里开始进一步分析?

非常感谢你!

问候朱尔斯

经过一个月的努力和使用变通办法,如切换到 Apache2 等......我想我找到了一个解决方案。

如我的原始问题所述,问题发生在 nginx 服务器已经运行了一段时间之后。 重新加载 nginx 服务器后,问题暂时消失了。 使用 apache2 我没有这个问题。 这样我就可以将问题与 nginx 本身隔离开来。

我现在尝试通过设置禁用 nginx 的请求缓存:

proxy_request_buffering off; <===

client_max_body_size 500M;
client_body_buffer_size 500M;

我还提高了测试的缓冲大小,现在可以正常工作了。 这个问题似乎与 Laravel、Graphql 或 PHP 完全无关。 对于可能偶然发现此主题的任何人,我将相应地编辑我的原始问题。 我希望这可以在将来对某人有所帮助。

如果使用9000端口,就会出现这个问题。 使用端口 8000。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM