php://input与$_POST有何不同?

4
我正在尝试使用Firefox的内容安全策略。基本上,它是网页的特殊头部,告诉浏览器哪些资源是有效的。
当某个资源无效因为它违反了策略时,Firefox会以JSON格式向给定的URI发送报告。
以下是典型的报告:
array(1) {
  ["csp-report"]=>
  array(4) {
    ["request"]=>
    string(71) "GET http://example.com/?function=detail&id=565 HTTP/1.1"
    ["request-headers"]=>
    string(494) "Host: example.com
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:2.0b10pre) Gecko/20110115 Firefox/4.0b10pre
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: es-ar,en-us;q=0.8,es;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Accept-Charset: UTF-8,*
Keep-Alive: 115
Connection: keep-alive
Referer: http://example.com/index.php?function=search&query=Pata+de+cambio+
Cookie: the cookie
"
    ["blocked-uri"]=>
    string(4) "self"
    ["violated-directive"]=>
    string(30) "inline script base restriction"
  }
}

内容类型为application/json; charset=UTF-8

现在,我期望这应该在REQUEST_METHOD==POST的情况下可在$_POST中使用,但是$_POST总是为空。我可以从php://input访问它,但问题是:为什么请求在$_POST中不可用?

我甚至无法使用filter_input,$_REQUEST也为空...

3个回答

8

$_POST 提供了表单变量,它们会在页面上显示如下:

POST /some_path HTTP/1.1

myvar=something&secondvar=somethingelse

但是您得到的不是有效的查询字符串。它可能看起来像这样:

POST /some_path HTTP/1.1

{'this':'is a JSON object','notice':'it\'s not a valid query string'}

php://input 是以原始形式返回头信息之后的所有内容,因此在这种情况下,我认为这是获取所需内容的唯一方法。


嗯,我想你说得有道理。但通常情况下,JSON数据可以在POST请求中正常发送。为什么在这种特殊情况下会失败,而通过JavaScript的POST请求却不会呢? - The Disintegrator
@The Disintegrator:我对此的经验非常少,但我使用的框架(ExtJS)可以将JSON对象转换为查询字符串。 - Brendan Long
@BrendanLong。你需要转义it's中的撇号。 - TRiG

8
如果请求以POST形式发送,它不一定编码为普通的application/x-www-form-urlencodedmultipart/form-data。如果Firefox发送JSON正文,则PHP不知道如何解码它。
您需要检查$_SERVER["HTTP_CONTENT_TYPE"]。如果它包含application/json,那么您必须确实读取php://stdin:
if (stripos($_SERVER["HTTP_CONTENT_TYPE"], "application/json")===0) {
     $_POST = json_decode(file_get_contents("php://input"));
// or something like that

1

它可以是其他几种HTTP请求类型之一(我现在知道有7种,还有几个占位符等待添加)。 我会打印$_REQUEST$_SERVER来查看它的实际到达情况。


没有报告。$_REQUEST为空,而$_SERVER具有典型数据。 - The Disintegrator

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接