如何嵌入JSON的HTML?
我有一个JSON阵列:
info = [{"name":"abc", "rank" : 1},{"name":"xyz", "rank":2},{"name":"pqr", "rank":3}];
我试图用jQuery
把它作为一个输入值的隐藏字段,并将其与POST
请求发送到服务器。
$('<form action="/info/saveAll" method="POST"/>')
.append($('<input type="hidden" name="info" value="' + JSON.stringify(info) + '">'))
.appendTo($(document.body))
.submit();
在服务器端,我访问info
的价值:
router.route('/saveAll')
.post((req, res) => {
let info = JSON.parse(req.body.info);
console.log(info); //SyntaxError: Unexpected end of JSON input
})
如果我不stringify
阵列之前提交,则typeof info
仍在门柱内侧返回字符串,当我尝试parse
字符串类型我得到语法错误一样SyntaxError: Unexpected token o in JSON at position 1
。
我知道这可以通过只是在做它通过Ajax post请求来完成,但我想围绕一个工作并不涉及一个Ajax请求。
任何帮助将是巨大的。
回答如下:你不能简单地连接一个JSON字符串转换成HTML,因为它可以包含保留的字符,如"
,需要被引用。只是注释掉.submit()
和检查你的代码加入到用DOM查看器的DOM在浏览器的开发者工具隐藏input
领域。你会看到value=
属性已损坏。
解决的办法是简单:使用encodeURI()
代替,即
.append($(
'<input type="hidden" name="info" value="' +
encodeURI(JSON.stringify(info) +
'\'>'))
和
let info = JSON.parse(decodeURI(req.body.info));
现在你会看到属性在DOM检查显示为有效的JSON字符串。当您选择隐藏input
元素的“编辑为HTML”菜单中,你会看到在HTML文本为value=
属性带引号的字符串。
从我与Firefox手动测试:
不正确
const info = {
test: "somestring",
html: '<input type="hidden" value="&"/>',
};
$('#demo').append($(
'<input type="hidden" value="' +
JSON.stringify(info)) +
'">'));
生成的HTML:
<input type="hidden" value="{" test":"somestring","html":"<input="">
正确
const info = {
test: "somestring",
html: '<input type="hidden" value="&"/>',
};
$('#demo').append($(
'<input type="hidden" value="' +
encodeURI(JSON.stringify(info))) +
'">'));
生成的HTML:
<input type="hidden" value="%7B%22test%22:%22somestring%22,%22html%22:%22%3Cinput%20type=%5C%22hidden%5C%22%20value=%5C%22&%5C%22/%3E%22%7D">
另一种选择是使用HTML实体进行编码/解码的方法,f.ex. this SO question,但所提供的答案似乎比我的解决方案更麻烦。它会更容易使用NPM模块代替,例如entities。
或者干脆...
......不依赖HTML字符串解析,让jQuery的做所有的工作。它也消除了需要在服务器端使用decodeURI()
:
const info = {
test: "somestring",
html: '<input type="hidden" value="&"/>',
},
input = $('<input type="hidden"/>')
.val(JSON.stringify(info));
$('#demo')
.append(input);
生成的HTML:
<input type="hidden" value="{"test":"somestring","html":"<input type=\"hidden\" value=\"&\"/>"}">