1

All,

I'm trying to pass a stringified json object as a GET parameter but the receiving URL seems unable to decode it, I am not sure why.

Here is the relevant code:

Client side Json object production (works fine):

function createJson(){
// This works fine.  It creates a json objects with three elements, the third being an array.
//(omitted code for brevity)
  return jsonData;
}

Client side ajax call (works fine):

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);
}

This yield the following URL: 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"

Server side treatment:

<?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());
}
?>

The result of the var_dumps are: string '{"setTitle":"test","setTags":"test ","set":[{"first":"Joe","last":"Doe","checked":true}]}"' (length=90)
null
string 'Json last error is 4' (length=20)

So why is json_decode() failing here? The json_last_error() result suggests a syntax error.

Edit: Note that json_decode also fails if I send a non encoded string:
If I build the param string without encoding it like this:

var rawSet=JSON.stringify(jsonData);
var params="set="+rawSet;
var url= "Ajax_recordSetGet.php?"+params;

Then the URL becomes Ajax_recordSetGet.php?set={"setTitle":"test","setTags":"test ","set":[{"first":"Joe","last":"Doe","checked":true}]}"

And the receiving URL var_dump yield the same error:
string '{"setTitle":"test","setTags":"test ","set":[{"first":"Joe","last":"Doe","checked":true}]}"' (length=90)
null
string 'Json last error is 4' (length=20)

4

2 回答 2

1

http://php.net/manual/en/function.urldecode.php

超全局变量 $_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;

但要注意注意事项

在您的服务器端:

$decodedSet=json_decode(base64_decode($set));
于 2013-09-10T20:56:47.400 回答
1

我不知道为什么,但是您的 URL 中有一个尾随双引号,这会扰乱 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().

作为概念的快速证明,请尝试$set = rtrim($set, '"')在解码之前在您的 PHP 代码中使用以删除该引号字符。

于 2013-09-10T21:27:03.120 回答