HTML string()打破了JSON

时间:2014-01-06 22:33:55

标签: javascript php jquery

我从我的页面收集一些数据,将数据存储在一个数组中,以便在页面上多次使用,并通过AJAX发送数组副本,将数据存储在PHP页面的数据库中。

我存储在数组中的一个数据是TinyMCE WYSIWYG编辑器的输出,因此它包含HTML,但刚刚发现这是一个问题 - 我将解释:

在我的WYSIWYG编辑器中输入一行文本并触发我的AJAX事件后,这是我的控制台中显示的JSON字符串,一切正常,数据库已发送并存储:

{"id":"229","topic":"","title":"","description":"","content":"<p>fgfgfdg.</p>","keywords":""}

如果我写两行文本,这是JSON字符串并且成功:

{"id":"229","topic":"","title":"","description":"","content":"<p>fgfgfdg.</p>\n<p>fgfgfdg</p>","keywords":""}

现在,如果我写了一行文字并按回车而没有在第二行输入任何内容,我会得到以下内容失败。

{"id":"229","topic":"","title":"","description":"","content":"<p>fgfgfdgdfgdfgdfgdfg.</p>\n<p>&nbsp;</p>","keywords":""}

似乎&nbsp;以某种方式破坏了我的JSON输出。我的PHP无法访问已解码的数组值,因为没有数组。 print_r(json_decode($json))什么都不返回。有人可以帮忙吗?

这是我的带有jQuery的HTML页面:

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<script>
var post_data = {};

post_data.id = post_id;
post_data.topic = topic;
post_data.title = title;
post_data.description = description;
post_data.content = tinyMCE.activeEditor.getContent();
post_data.keywords = keywords;

post_data = JSON.stringify(post_data);

save_post_request = $.ajax({
    url: 'ajax/save-post.php',
    type: 'POST',
    data: "save_mode="+save_mode+"&post_data="+post_data,
    dataType: 'text',
    cache: false
});
</script>

这是我的PHP页面:

header('Content-type: application/json; charset=UTF-8');

$post_data = isset($_POST['post_data']) ? $_POST['post_data'] : null;
$post_data_arr = json_decode($post_data, true);
$post_id = $post_data_arr['id'];
$topic = $post_data_arr['topic'];
// others
$content = $post_data_arr['content'];

if (!$post_data_arr['id']) {
    // fails here
    // id is not accessible when the JSON contains <p>&nbsp;</p> in the 'content' item
}

这就是Firebug所说的:

enter image description here

1 个答案:

答案 0 :(得分:9)

您将JSON放入某些URL编码数据,但您不是URL编码它。

&字符在URL编码数据中具有特殊含义(它分隔键/值对),因此这意味着您正在破坏数据。

使用encodeURIComponent函数对数据进行正确编码,然后再将其添加到字符串中:

data: "save_mode="+encodeURIComponent(save_mode)+"&post_data="+encodeURIComponent(post_data),

但是,由于您使用的是jQuery,因此您不应该首先手动构建URL编码数据。 jQuery可以为你做到。传递data对象而不是字符串:

data: {
    save_mode: save_mode,
    post_data: post_data
},