Javascript 在 HTML 属性中存储 JSON 的最佳方式?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7322682/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Best way to store JSON in an HTML attribute?
提问by BadHorsie
I need to put a JSON object into an attribute on an HTML element.
我需要将 JSON 对象放入 HTML 元素的属性中。
The HTML does not have to validate.Answered by Quentin: Store the JSON in a
data-*
attribute, which is valid HTML5.The JSON object could be any size - i.e. huge
Answered by Maiku Mori: The limit for an HTML attribute is potentially 65536 characters.
What if the JSON contains special characters? e.g.
{foo: '<"bar/>'}
Answered by Quentin: Encode the JSON string before putting it into the attribute, as per the usual conventions. For PHP, use the
htmlentities()
function.
HTML 不必验证。Quentin 回答:将 JSON 存储在一个
data-*
属性中,这是有效的 HTML5。JSON 对象可以是任何大小 - 即巨大
Maiku Mori 回答:HTML 属性的限制可能是 65536 个字符。
如果 JSON 包含特殊字符怎么办?例如
{foo: '<"bar/>'}
Quentin 回答:按照通常的约定,在将 JSON 字符串放入属性之前对其进行编码。对于 PHP,请使用函数.
htmlentities()
EDIT - Example solution using PHP and jQuery
编辑 - 使用 PHP 和 jQuery 的示例解决方案
Writing the JSON into the HTML attribute:
将 JSON 写入 HTML 属性:
<?php
$data = array(
'1' => 'test',
'foo' => '<"bar/>'
);
$json = json_encode($data);
?>
<a href="#" data-json="<?php echo htmlentities($json, ENT_QUOTES, 'UTF-8'); ?>">CLICK ME</a>
Retrieving the JSON using jQuery:
使用 jQuery 检索 JSON:
$('a').click(function() {
// Read the contents of the attribute (returns a string)
var data = $(this).data('json');
// Parse the string back into a proper JSON object
var json = $.parseJSON($(this).data('json'));
// Object now available
console.log(json.foo);
});
采纳答案by Quentin
The HTML does not have to validate.
HTML 不必验证。
Why not? Validation is really easy QA that catches lots of mistakes. Use an HTML 5 data-*
attribute.
为什么不?验证是非常简单的 QA,可以捕获很多错误。使用 HTML 5data-*
属性。
The JSON object could be any size (i.e. huge).
JSON 对象可以是任何大小(即巨大的)。
I've not seen any documentation on browser limits to attribute sizes.
我还没有看到任何关于浏览器对属性大小的限制的文档。
If you do run into them, then store the data in a <script>
. Define an object and map element id
s to property names in that object.
如果确实遇到它们,请将数据存储在<script>
. 定义一个对象并将元素id
s映射到该对象中的属性名称。
What if the JSON contains special characters? (e.g. {test: '<"myString/>'})
如果 JSON 包含特殊字符怎么办?(例如 {test: '<"myString/>'})
Just follow the normal rules for including untrusted data in attribute values. Use &
and "
(if you're wrapping the attribute value in double quotes) or '
(if you're wrapping the attribute value in single quotes).
只需遵循在属性值中包含不受信任数据的常规规则即可。使用&
and "
(如果您将属性值括在双引号中)或'
(如果您将属性值括在单引号中)。
Note, however, that that is not JSON (which requires that property names be strings and strings be delimited only with double quotes).
但是请注意,这不是 JSON(它要求属性名称是字符串,字符串只能用双引号分隔)。
回答by Mike Samuel
Depending on where you put it,
看你把它放在哪里
- In a
<div>
as you asked, you need to ensure that the JSON does not contain HTML specials that could start a tag, HTML comment, embedded doctype, etc. You need to escape at least<
, and&
in such a way that the original character does not appear in the escaped sequence. - In
<script>
elements you need to ensure that the JSON does not contain an end tag</script>
or escaping text boundary:<!--
or-->
. - In event handlers you need to ensure that the JSON preserves its meaning even if it has things that look like HTML entities and does not break attribute boundaries (
"
or'
).
- 在 a
<div>
正如您所问的那样,您需要确保 JSON 不包含可以开始标记、HTML 注释、嵌入的文档类型等的 HTML 特殊内容。您至少需要转义<
,并且&
以这样的方式原始字符不会出现在转义序列中。 - 在
<script>
元素中,您需要确保 JSON 不包含结束标记</script>
或转义文本边界:<!--
或-->
。 - 在事件处理程序中,您需要确保 JSON 保留其含义,即使它具有看起来像 HTML 实体的内容并且不会破坏属性边界(
"
或'
)。
For the first two cases (and for old JSON parsers) you should encode U+2028 and U+2029 since those are newline characters in JavaScript even though they are allowed in strings unencoded in JSON.
对于前两种情况(以及旧的 JSON 解析器),您应该对 U+2028 和 U+2029 进行编码,因为它们是 JavaScript 中的换行符,即使它们在 JSON 中未编码的字符串中也是允许的。
For correctness, you need to escape \
and JSON quote characters and it's never a bad idea to always encode NUL.
为了正确起见,您需要转义\
和 JSON 引号字符,并且始终对 NUL 进行编码绝不是一个坏主意。
If the HTML might be served without a content encoding, you should encode +
to prevent UTF-7 attacks.
如果 HTML 可能在没有内容编码的情况下提供,您应该编码+
以防止UTF-7 攻击。
In any case, the following escaping table will work:
在任何情况下,以下转义表都可以使用:
- NUL ->
\u0000
- CR ->
\n
or\u000a
- LF ->
\r
or\u000d
"
->\u0022
&
->\u0026
'
->\u0027
+
->\u002b
/
->\/
or\u002f
<
->\u003c
>
->\u003e
\
->\\
or\u005c
- U+2028->
\u2028
- U+2029 ->
\u2029
- 空 ->
\u0000
- CR ->
\n
或\u000a
- LF ->
\r
或\u000d
"
->\u0022
&
->\u0026
'
->\u0027
+
->\u002b
/
->\/
或\u002f
<
->\u003c
>
->\u003e
\
->\\
或\u005c
- U+2028->
\u2028
- U+2029 ->
\u2029
So the JSON string value for the text Hello, <World>!
with a newline at the end would be "Hello, \u003cWorld\u003e!\r\n"
.
因此,末尾Hello, <World>!
带有换行符的文本的 JSON 字符串值将是"Hello, \u003cWorld\u003e!\r\n"
.
回答by Sergey Kamardin
Another way you can do it – is put json data inside <script>
tag, but not with type="text/javascript"
, but with type="text/bootstrap"
or type="text/json"
type, to avoid javascript execution.
另一种方法是将 json 数据放在<script>
标签中,但不是 with type="text/javascript"
,而是 withtype="text/bootstrap"
或type="text/json"
type ,以避免 javascript 执行。
Then, in some place of your program, you can ask for it in this way:
然后,在你的程序的某个地方,你可以通过这种方式来请求它:
function getData(key) {
try {
return JSON.parse($('script[type="text/json"]#' + key).text());
} catch (err) { // if we have not valid json or dont have it
return null;
}
}
On server side, you can do something like this (this example with php and twig):
在服务器端,您可以执行以下操作(此示例使用 php 和twig):
<script id="my_model" type="text/json">
{{ my_model|json_encode()|raw }}
</script>
回答by Pavel Petrov
Another option is to base64 encode the JSON string and if you need to use it in your javascript decode it with the atob()
function.
另一种选择是对 JSON 字符串进行 base64 编码,如果您需要在 javascript 中使用它,请使用该atob()
函数对其进行解码。
var data = JSON.parse(atob(base64EncodedJSON));
回答by jayM
You can use knockoutjs,
你可以使用knockoutjs,
<p>First name: <strong data-bind="text: firstName" >todo</strong></p>
<p>Last name: <strong data-bind="text: lastName">todo</strong></p>
knockout.js
淘汰赛.js
// This is a simple *viewmodel* - JavaScript that defines the data and behavior of your UI
function AppViewModel() {
this.firstName = "Jayson";
this.lastName = "Monterroso";
}
// Activates knockout.js
ko.applyBindings(new AppViewModel());
Output
输出
First name: Jayson Last name: Monterroso
名字:Jayson 姓氏:Monterroso
Check this: http://learn.knockoutjs.com/
检查这个:http: //learn.knockoutjs.com/
回答by Matchu
Nothing fancy here. From PHP, give the JSON string a run through htmlspecialchars
to make sure no special characters can be interpreted as HTML. From Javascript, no escaping necessary; just set the attribute and you're good to go.
这里没什么好看的。在 PHP 中,运行 JSON 字符串htmlspecialchars
以确保没有特殊字符可以解释为 HTML。来自 Javascript,无需转义;只需设置属性即可。
回答by Faiyet
What you can do is use cdataaround your element/s like this
您可以做的是像这样在您的元素周围使用 cdata
<![CDATA[ <div class='log' mydata='${aL.logData}'>${aL.logMessage}</div> ]]>
where mydata is a raw json string. Hope this helps you and others.
其中 mydata 是原始 json 字符串。希望这对您和其他人有所帮助。
回答by Matthew D Auld
Another thought that could be used is store the JSON data as a base64 string in the attribute and then using window.atob
or window.btoa
to restore it to usable JSON data.
另一个可以使用的想法是将 JSON 数据作为 base64 字符串存储在属性中,然后使用window.atob
或window.btoa
将其恢复为可用的 JSON 数据。
<?php
$json = array("data"=>"Some json data thing");
echo "<div data-json=\"".base64_encode(json_encode($json))."\"></div>";
?>
回答by Crashalot
For simple JSON objects, the code below would work.
对于简单的 JSON 对象,下面的代码可以工作。
Encode:
编码:
var jsonObject = { numCells: 5, cellWidth: 1242 };
var attributeString = escape(JSON.stringify(jsonObject));
Decode:
解码:
var jsonString = unescape(attributeString);
var jsonObject = JSON.parse(jsonString);