所有
我正在尝试将字符串化的json对象作为GET参数传递,但接收URL似乎无法对其进行解码,我不确定原因。
以下是相关代码:
客户端Json对象生产(工作正常):
function createJson(){
// This works fine. It creates a json objects with three elements, the third being an array.
//(omitted code for brevity)
return jsonData;
}
客户端ajax调用(工作正常):
function recordSetGet(jsonData){
request = createRequest();
var rawSet=JSON.stringify(jsonData);
var encodedSet=encodeURIComponent(rawSet);
var params="set="+encodedSet;
var url= "Ajax_recordSetGet.php?"+params;
request.open("GET", url, true);
request.onreadystatechange = function(){}
request.send(null);
}
这会产生以下网址:Ajax_recordSetGet.php?set=%7B%22setTitle%22%3A%22test%22%2C%22setTags%22%3A%22test%20%22%2C%22set%22%3A%5B%7B%22first%22%3A%22Joe%22%2C%22last%22%3A%22Doe%22%2C%22checked%22%3Atrue%7D%5D%7D"
服务器端处理:
<?php
header('Content-Type:text/html; charset=UTF-8');
if(!session_id()){
session_start();
}
if(isset($_GET['set'])){
$set=$_GET['set'];//This is the URI encoded string
var_dump ($set);
var_dump (json_decode($set));
var_dump ("Json last error is ".json_last_error());
}
?>
var_dumps的结果是:
string '{"setTitle":"test","setTags":"test ","set":[{"first":"Joe","last":"Doe","checked":true}]}"' (length=90)
null
string 'Json last error is 4' (length=20)
那么为什么json_decode()
在这里失败了? json_last_error()
结果表明语法错误。
编辑:请注意,如果我发送一个非编码字符串,json_decode也会失败:
如果我构建param字符串而不对它进行编码:
var rawSet=JSON.stringify(jsonData);
var params="set="+rawSet;
var url= "Ajax_recordSetGet.php?"+params;
然后网址变为Ajax_recordSetGet.php?set={"setTitle":"test","setTags":"test ","set":[{"first":"Joe","last":"Doe","checked":true}]}"
接收URL var_dump产生相同的错误:
string '{"setTitle":"test","setTags":"test ","set":[{"first":"Joe","last":"Doe","checked":true}]}"' (length=90)
null
string 'Json last error is 4' (length=20)
答案 0 :(得分:1)
http://php.net/manual/en/function.urldecode.php
superglobals $ _GET和$ _REQUEST已经解码。在$ _GET或$ _REQUEST中的元素上使用urldecode()可能会产生意外和危险的结果。
尝试不同的方式。我建议对json字符串进行base64编码。
而不是:
var rawSet=JSON.stringify(jsonData);
var encodedSet=encodeURIComponent(rawSet);
var params="set="+encodedSet;
var url= "Ajax_recordSetGet.php?"+params;
这样做:
var rawSet=JSON.stringify(jsonData);
var encodedSet=btoa(rawSet);
var params="set="+encodedSet;
var url= "Ajax_recordSetGet.php?"+params;
但要注意caveats!
在您的服务器端:
$decodedSet=json_decode(base64_decode($set));
答案 1 :(得分:1)
我不知道为什么,但是您的网址中有一个尾随双引号会混淆JSON解码过程。
...%7D%5D%7D" <- Trailing double quote
此引号也显示在转储set变量中:
...true}]}"' (length=90) <- double quote is inside the string, the single quote is part of the var_dump output.
这个双引号必须在Javascript代码中引入,虽然我看不到应该发生的地方。但是你的调试应该在系统的那个部分进行。
请注意,您不得对作为“set”参数传递的字符串进行urldecode,因为PHP已经为您完成了解码。但是使用尾随双引号,您无法调用json_decode()
。
作为概念的快速证明,请在解码前尝试在PHP代码中使用$set = rtrim($set, '"')
以删除该引号字符。