nginx 上的 $_POST 为空

Ang*_*alu 3 php ubuntu nginx nginx-config ubuntu-18.04

我的问题似乎与$_POST 类似,为空。Nginx OSx$_POST 在 nginx 中为空$_GET 已填充,但 $_REQUEST 为空,但是我找不到适合我的解决方案。

长话短说,我无法将 POST 请求发送到server.php服务器上指定的文件。

假设 myserver.php仅包含以下内容:

<?php var_dump($_REQUEST);
Run Code Online (Sandbox Code Playgroud)

我的sites-available/domain.tld文件包含以下内容:

server {

    root /var/www/domain.tld/current/dist;
    index index.html index.htm;

    server_name domain.tld;


    location / {
        try_files $uri $uri/ index.php?$query_string =404;
    }

    location ~ \.php$ {
            #limit_except POST {
            #    allow 127.0.0.1;
            #    deny  all;
            #}

            #if ( $request_method !~ ^POST$ ) {
            #    return 405;
            #}

            include snippets/fastcgi-php.conf;

            fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
            #fastcgi_param REQUEST_METHOD $request_method;
            fastcgi_param  REQUEST_METHOD     $echo_request_method;
            fastcgi_param CONTENT_TYPE $content_type;
            fastcgi_param CONTENT_LENGTH $content_length;
            fastcgi_param REQUEST_BODY $request_body;
            fastcgi_param QUERY_STRING $query_string;

    }

    location ~ /\.ht {
            deny all;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/domain.tld/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/domain.tld/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

server {
    server_name www.domain.tld;
    return 301 $scheme://domain.tld$request_uri;
}

server {
    if ($host = domain.tld) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


        listen 80;

        server_name domain.tld;
    return 404; # managed by Certbot

}
Run Code Online (Sandbox Code Playgroud)

无论我发出什么“POST”请求,server.php都不会发送任何参数。

的输出server.php将是array(0) {}

其他一些信息:

  • 请求是在请求 URL 上发出的:https://domain.tld/server.php

  • 请求方式:POST

  • 状态代码:200 OK

发送的 GET 请求https://domain.tld/server.php?foo=bar将显示foo发送过来的正确变量,其值为bar

如果需要,我可以提供有关请求本身的详细信息。axios(在应用程序中使用vue)。

请指教...

B. *_*ing 6

这个答案可能有点晚了,但为了其他遇到同样问题的人:

问题原来是Content-Type标头的值为application/json。当 PHP 解析数据以放入$_POST超级全局时,它期望此标头具有值application/x-www-form-urlencodedmultipart/form-data,即 Web 标准内容类型。接收application/json内容类型数据时,您必须从流中访问它php://input

解决方案最终看起来像这样:

$json_string_data = file_get_contents('php://input');
$decoded_data = json_decode($json_string_data, true);
Run Code Online (Sandbox Code Playgroud)

如果您的应用程序希望数据在超级全局中可用$_POST,那么可以使用以下(诚然是hacky)解决方案:

$json_string_data = file_get_contents('php://input');
$decoded_data = json_decode($json_string_data, true);
$_POST = $decoded_data;
Run Code Online (Sandbox Code Playgroud)

或者,为了简洁起见:

$_POST = json_decode(file_get_contents('php://input'), true);
Run Code Online (Sandbox Code Playgroud)