POST请求发送JSON对象

3
我想要使用POST方法发送一个JSON对象。
var user = {
    "first_name": first_name.value,
    "last_name": last_name.value,
    "age": age.value,
    "email": email.value
};   

这是我发送对象的方式:

var request;
var url = 'ajax_serverside_JSON.php';
var destination;

function ajax_call(src, jsonObj, dst, method) {

    this.src = src;
    destination = dst;
    this.objJSON = jsonObj;
    this.request = getXMLHttpRequest();
    this.request.onreadystatechange = getResponse;
    if (method == 'POST') {
        sendPostRequest(objJSON);
    }
    return;
}

function sendPostRequest(objJSON) {
    request.open('POST', url, true);
    request.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
    request.send(JSON.stringify(objJSON));
    return;
}

function getXMLHttpRequest() {
    try {
        if (window.XMLHttpRequest) {
            // code for IE7+, Firefox, Chrome, Opera,Safari
            request = new XMLHttpRequest();
        } else {
            // code for IE6, IE5
            request = new ActiveXObject("Microsoft.XMLHTTP");
        }
    } catch (e) {
        alert('The browser doesn\'t support AJAX: ' + e);
        request = false;
    }
    return request;
}

function getResponse() {
    if (request.readyState == 4 && request.status == 200) {
        document.getElementById(destination).innerHTML += request.response;
    }
}

问题:我该如何在服务器端的PHP中读取对象?发送的JSON的关键是什么? echo var_dump($_POST)将显示以下内容:
  array (size=0)
  empty

什么是问题?
编辑后:
我修改了我的代码为:
this.objJSON = jsonObj;

并且

request.send("user=" + JSON.stringify(this.objJSON));

我试着阅读JSON对象:

<?php
if (isset ( $_POST ['user'] )) {
    $obj = json_decode ( $_POST ['user'] );
    echo "isset";
} else {
    echo "is not set ";
    echo var_dump ( $_POST );
}
?>

...还是同样的问题:

is not set

array (size=0)
  empty
6个回答

3

我不确定PHP能否自动将JSON解析为$_POST变量。您应该将JSON放入普通POST变量的值中:

request.send('data=' + encodeURIComponent(JSON.stringify(objJSON));

并使用默认的Content-Type。然后在PHP中,您可以这样做:

var_dump(json_decode($_POST['data']));

你还需要修复一个Javascript变量,就像Niels Keurentjes的回答中所解释的一样。


我不知道为什么 request.send('data=' + encodeURIComponent(JSON.stringify(this.objJSON))); 不起作用... 它给了我 Undefined index: data,就像之前一样。 - Iulian Rosca
我还使用Firebug检查了POST选项卡,发现有一个条目"data=%7B%22first_name%22%3A%22das%22%2C%22last_name%22%3A%22dsa%22%2C%22age%22%3A%22dsadsa%22%2C%22email%22%3A%22dsadsa%22%7D"。 - Iulian Rosca
那个数据看起来正确。你把 setRequestHeader 调用给删掉了吗? - Barmar
抱歉,我不确定。我只是使用jQuery并让它自己处理细节。 - Barmar
字符串 'data={"first_name":"fdsfds","last_name":"fdsf","age":"dsfds","email":"fdsdfs"}' (长度=78) - Iulian Rosca

2

将您的函数分解为其核心3行:

function ajax_call(src, jsonObj, dst, method) {

jsonOBJ被设置为本地变量。

this.objJSON = jsonObj;

jsonOBJ 被复制到 this.objJSON 中。

sendPostRequest(objJSON);

由于Javascript不会自动将this视为本地范围的一部分,因此仍然没有本地变量objJSON,因此发送null,因此$_POST为空。

发送jsonOBJthis.objJSON,它将正常工作。


你能否请查看一下“编辑后”的内容,也许我有些地方没理解对。感谢您的帮助。 - Iulian Rosca

2

尝试:

request.send("obj="+JSON.stringify(objJSON));

这是一个键值对,我猜你可能缺少了键。


2

对于您的原始Ajax请求,您需要从php://input读取请求体并进行解码。

<?php
$post = json_decode(file_get_contents('php://input'));
if (isset ( $post ['user'] )) {
    echo "isset";
} else {
    echo "is not set ";
    echo var_dump ( $post );
}

1
这是处理JSON的正确方式,将JSON放在编码形式的已发布变量(get/post)中只会增加服务器端的工作量。 - Rahly

1
<script>
var user = {
                "first_name" : first_name.value,
                "last_name" : last_name.value,
                "age" : age.value,
                "email" : email.value
            };

$.customPOST = function(data,callback){
  $.post('your_php_script.php',data,callback,'json');
}

$(document).ready(function() {
    //suppose you have a button "myButton" to submit your data
    $("#myButton").click(function(){
        $.customPOST(user,function(response){
         //on the server side you will have :
         //$_POST['first_name'], $_POST['last_name'], .....
         //server will return an OBJECT called "response"
         //in "index.php" you will need to use json_encode();
         //in order to return a response to the client
         //json_encode(); must have an array as argument
         //the array must be in the form : 'key' => 'value'
        });
        return false;
    });
</script>

0
我将尝试为原问题带来一些清晰度,或许能够消除一些潜在的困惑。Rosca的问题或困惑是,在使用PHP发布JSON对象时,$_POST无法正常工作。原因是,虽然请求是以POST方式发送的,但它并不是作为标准的“表单”POST请求发送的。在标准的表单POST中,请求Content-Type应该是“application/x-www-form-urlencoded”,而不是“application/json”。此外,POST请求的主体应该是一个URL编码的查询字符串,而不是一个JSON编码的字符串。它们的格式不同。查询字符串可能看起来像id=134626&type=car,而JSON编码的字符串可能看起来像["id"="134526","type":"car"]。由于原始请求的发送方式,它发送的是JSON对象数据,而不是URL编码的表单数据。因此,当您执行类似于$_POST ["id"]的操作时,PHP会返回错误,因为没有发送表单数据。其他人提供的建议是让PHP读取请求主体并将其处理为JSON对象。如果您将POST请求作为JSON对象发送,并在服务器端将其处理为JSON对象,则可以完美地解决这个问题!
另一件你可以做的事情是将数据作为url编码的表单数据内容(application/x-www-form-urlencoded)发送,将数据添加为有效的查询字符串,并在服务器端处理它作为标准表单提交请求。如果你这样做,那么是的,你可以使用PHP中的$_POST["id"]来获取"id"参数的值。以下是一些将JSON对象转换为查询字符串的javascript代码:
function obj2qs(param
 var queryString = "";
 var sep = "";
 $.each(Object(params), function(key, value) {
    var input = document.createElement('input');
    queryString += sep + encodeURIComponent(key) + "=" + encodeURIComponent(value);
    sep = "&";
 });
 return queryString;
}

在上面的代码中,“params”是您想要转换为查询字符串的JSON对象。
以下是如何更改Rosca的编码,以便像标准表单提交一样发送:
function sendPostRequest(objJSON) {
    request.open('POST', url, true);
    request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
    request.send(obj2qs(objJSON));
}

发送请求作为标准表单请求的优势在于,您可以轻松地创建一个简单的HTML页面来测试执行POST操作的页面。

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