【问题标题】:Send JSON data to PHP using XMLHttpRequest w/o jQuery使用 XMLHttpRequest w/o jQuery 将 JSON 数据发送到 PHP
【发布时间】:2012-03-19 22:28:25
【问题描述】:

我正在尝试使用 XMLHttpRequest 对象从表单发送 JSON 数据。我可以使用以下功能发送数据。 FireBug 中没有显示错误,请求中的 JSON 数据由 FireBug 正确显示。

但是,我将数据发送到 echo.php,只是返回内容:

<?php
print_r($_POST);
print_r($_GET);
foreach (getallheaders() as $name => $value) {
    echo "$name: $value\n";
}
echo file_get_contents('php://input');
?>

POST 数组始终为空,但我可以看到 file_get_contents 返回的 JSON 字符串。这是怎么发生的?我做错了什么?

echo.php 的输出

Array
(
)
Array
(
)
Host: localhost
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: eo,de-de;q=0.8,de;q=0.6,en-us;q=0.4,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Type: application/json; charset=utf-8
Referer: http://localhost/form.html
Content-Length: 88
Cookie: {{..to much data..}}
Pragma: no-cache
Cache-Control: no-cache
{"type":"my_type","comment":"commented"}

发送函数:

function submit(){
    var data={};
    data.type=document.form.type.value;
    data.comment=document.form.comment.value;

    //get right XMLHttpRequest object for current browsrer
    var x=ajaxFunction();

    var string = JSON.stringify(data);

    x.open('POST','echo.php',true);
    x.setRequestHeader('Content-type','application/json; charset=utf-8');
    x.setRequestHeader("Content-length", string.length);
    x.setRequestHeader("Connection", "close");

    x.onreadystatechange = function(){
        if (x.readyState != 4) return;
        if (x.status != 200 && x.status != 304) {
            alert('HTTP error ' + req.status);
            return;
        }

        data.resp = JSON.parse(x.responseText);
        if(data.resp.status=='success'){
            alert('That worked!');
        }else{
            alert('That didn\'t work!');
        }
    }
    x.send(string);

    return false; //prevent native form submit
}

【问题讨论】:

  • alert('HTTP error ' + req.status); ==> req 没有​​定义,你的意思是x 吗?

标签: php json post xmlhttprequest


【解决方案1】:

PHP 不会像处理表单编码或多部分请求那样自动处理 JSON 请求。如果您想使用 JSON 向 PHP 发送请求,您基本上可以使用 file_get_contents() 正确执行此操作。如果你想将这些变量合并到你的全局 $_POST 对象中,你可以,但我不建议这样做,因为它可能会让其他开发人员感到困惑。

// it's safe to overwrite the $_POST if the content-type is application/json
// because the $_POST var will be empty
$headers = getallheaders();
if ($headers["Content-Type"] == "application/json")
    $_POST = json_decode(file_get_contents("php://input"), true) ?: [];

快速说明:您不应该为 application/json 发送带有 Content-Type 的字符集。这只能与 text/* Content-Types 一起发送。

【讨论】:

  • 这个 sn-p 不能开箱即用。 getallheaders() 函数在 PHP-FPM 中不存在。此外,甚至没有必要这样做,因为您可以安全地获得$_SERVER["HTTP_CONTENT_TYPE"]
  • getallheaders 在 PHP-FPM v7.3 中可用。
【解决方案2】:

您忘记在发送函数中命名变量。 使用它的好方法是

x.send('name1='+string+'&name2=value2'); 

鉴于此,我认为您将不得不更改 content-length 标头。我认为发送它没有用。

您可以做的另一件事是尝试使用 GET 方法。 你也可以尝试用那个来改变你的内容类型标题:

xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded")

【讨论】:

  • 已经尝试过了,但它不会改变行为。我在 PHP 中收到 data={"type":"my_type","comment":"commented"},但 $_POST 是空的。我必须逃避string吗?怎么样?
  • 您可以做的一件事是将您的内容类型标头替换为该标头:x.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
  • 谢谢!那行得通!对我来说似乎很不方便。但如果这是唯一的方法,我会这样做。
  • 哦,我使用转义方法从以下位置转义了 JSON 字符串:stackoverflow.com/a/9204218/487846
  • 如果您使用x.setRequestHeader("Content-type", "application/x-www-form-urlencoded"),您发送的是表单数据,而不是 JSON 数据。 Rich remer 下面的答案是正确的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-19
  • 1970-01-01
  • 1970-01-01
  • 2013-11-03
  • 2013-12-21
相关资源
最近更新 更多