开发者

String JSON-encoded with ExtJS can't be decoded with json_decode in PHP

I'd like to store data from an input field to a database. However, when the user decides to enter some backslashes or quotes, i'm screwed.

I'm using the following code on the client side. The value of mystring is in fact read from an input field.

mydata = Ext.encode({
    mystring : "foo '\' bar ' \0x00\""
});

Ext.Ajax.request({
  url: '/test.php',
  params: { data: mydata }
});

On the server, print_r($_POST) gives me

array(
  ['data'] => '{"mystring":"foo '' bar ' \u0000x00\""}'
)

So, I lost the backslash after foo, and the \0x became \u00, and

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

fails and returns

NULL

In an other case, when the user uses quotes, I get

mydata = Ext.encode({
    {"mystring":"foo '\"' bar '"}
});

and I end up on the PHP side with $_POST

array(
  ['data'] => '{"mystring":"foo '"' bar '"}'
)

which too is no valid input for json_decode().

I want the user input literally. I'd like to let my database wrapp开发者_开发问答er take care of the escaping stuff before the INSERT command, but how can I send arbitrary strings, potentially containing any amount of slashes, backslashes, double and single quotes safely to my PHP script and json_decode it successfully?

I already thought about base64 encoding, but that is not very much an option.

See http://dev.sencha.com/deploy/dev/docs/?class=Ext.util.JSON for documentation.


Edit:

The data is read from the store of an Ext.grid.EditorGridPanel myGrid. The whole script has about 2.500 LoC, so I only post an excerpt here. I also changed some variable names to make the whole stuff more readable.

var modRec = myGrid.getStore().getModifiedRecords();
var data = new Array();
var len = modRec.length - 1;
for (f = len; f > -1; --f) {
    var a = {};
    var changes = modRec[f].getChanges();
    for (var name in changes) {
        if ('function' == typeof changes[name]) {
            continue;
        }
        a[name] = changes[name];
    }
    data.push(a);
}

Ext.Ajax.request({
    url: '/test.php',
    params: { Ext.encode(data) }
});

The result is the same as above. When a user enters a double quote into the editor field of the grid cell editor, which is an Ext.form.TextField, the string is not encoded and decoded correctly.


When you get your POST data, run it through stripslashes.

$grid_data = json_decode ( stripslashes ( $_POST['grid_data'] ), true);


You're saying that the values for 'mystring' are read from an input field, o in this case it should work, but in your example you pasted the strings but you have unescaped backslashes in it so JavaScript escapes the following character.

the Ext.encode (or JSON native objects) works correctly when reading a user-entered string:

Use the following HTML code:

<html>
<head>
<title>Test Page</title>
<script src="https://www.google.com/jsapi"></script>
<script>
google.load('jquery','1');
google.load("ext-core", "3.1.0");
</script>
</head>
<body>
<input type="text" id="test" />
</body>
</html>

Manually enter this exact string in the box: foo '\' bar ' \0x00\"

And then run the following javascript code from the console and you will see the first two log are showing the expected JSON output, the second while technically good has the string parsed from the javascript engine before it's processed by the code:

var x = $('#test').val();
console.log(JSON.stringify(x));
console.log(Ext.encode(x));

var y = "foo '\' bar ' \0x00\""
console.log(JSON.stringify(y));
console.log(Ext.encode(y));

You should get the following results:

"foo '\\' bar ' \\0x00\\\""
"foo '\\' bar ' \\0x00\\\""
"foo '' bar ' \u0000x00\""
"foo '' bar ' \u0000x00\""

Hope this helps!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜