$_POST 在 nginx 上是空的
$_POST is empty on nginx
我的问题似乎与 $_POST is empty. Nginx OSx , $_POST is empty in nginx and $_GET filled but $_REQUEST is empty 类似,但是我找不到适合我的解决方案。
长话短说,我无法将我的 POST 请求发送到服务器上名为 server.php
的文件。
让我们假设我的 server.php
只包含如下内容:
<?php var_dump($_REQUEST);
我的 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
}
无论我在 server.php
上发出什么 'POST' 请求,都不会发送任何参数。
server.php
的输出将是 array(0) {}
一些其他信息:
根据请求 URL 提出请求:https://domain.tld/server.php
请求方法:POST
状态码:200 OK
像 https://domain.tld/server.php?foo=bar
这样发送的 GET 请求会显示正确的 foo
变量发送过来,其值为 bar
如果需要,我可以提供有关请求本身的详细信息。 (在 vue
应用中使用 axios
)。
请指教...
这个答案可能有点晚了,但为了其他遇到同样问题的人:
问题原来是 Content-Type
header 的值为 application/json
。当 PHP 解析数据以放入 $_POST
超级全局时,它期望此 header 具有值 application/x-www-form-urlencoded
或 multipart/form-data
,Web 标准内容类型。接收 application/json
内容类型数据时,您必须从 php://input
流访问它。
解决方案最终看起来像这样:
$json_string_data = file_get_contents('php://input');
$decoded_data = json_decode($json_string_data, true);
如果您的应用程序希望数据在 $_POST
超级全局中可用,则可以使用以下(公认的 hacky)解决方案:
$json_string_data = file_get_contents('php://input');
$decoded_data = json_decode($json_string_data, true);
$_POST = $decoded_data;
或者,为了简洁起见:
$_POST = json_decode(file_get_contents('php://input'), true);
我的问题似乎与 $_POST is empty. Nginx OSx , $_POST is empty in nginx and $_GET filled but $_REQUEST is empty 类似,但是我找不到适合我的解决方案。
长话短说,我无法将我的 POST 请求发送到服务器上名为 server.php
的文件。
让我们假设我的 server.php
只包含如下内容:
<?php var_dump($_REQUEST);
我的 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
}
无论我在 server.php
上发出什么 'POST' 请求,都不会发送任何参数。
server.php
的输出将是 array(0) {}
一些其他信息:
根据请求 URL 提出请求:
https://domain.tld/server.php
请求方法:
POST
状态码:
200 OK
像 https://domain.tld/server.php?foo=bar
这样发送的 GET 请求会显示正确的 foo
变量发送过来,其值为 bar
如果需要,我可以提供有关请求本身的详细信息。 (在 vue
应用中使用 axios
)。
请指教...
这个答案可能有点晚了,但为了其他遇到同样问题的人:
问题原来是 Content-Type
header 的值为 application/json
。当 PHP 解析数据以放入 $_POST
超级全局时,它期望此 header 具有值 application/x-www-form-urlencoded
或 multipart/form-data
,Web 标准内容类型。接收 application/json
内容类型数据时,您必须从 php://input
流访问它。
解决方案最终看起来像这样:
$json_string_data = file_get_contents('php://input');
$decoded_data = json_decode($json_string_data, true);
如果您的应用程序希望数据在 $_POST
超级全局中可用,则可以使用以下(公认的 hacky)解决方案:
$json_string_data = file_get_contents('php://input');
$decoded_data = json_decode($json_string_data, true);
$_POST = $decoded_data;
或者,为了简洁起见:
$_POST = json_decode(file_get_contents('php://input'), true);