在 DOM 中嵌入任意 JSON 的最佳实践?

发布于 2025-01-06 09:08:44 字数 562 浏览 1 评论 0原文

我正在考虑像这样在 DOM 中嵌入任意 JSON:

<script type="application/json" id="stuff">
    {
        "unicorns": "awesome",
        "abc": [1, 2, 3]
    }
</script>

这类似于在 DOM 中存储任意 HTML 模板以供以后与 JavaScript 模板引擎一起使用的方式。在这种情况下,我们稍后可以检索 JSON 并使用以下方法解析它:

var stuff = JSON.parse(document.getElementById('stuff').innerHTML);

这可行,但这是最好的方法吗?这是否违反任何最佳实践或标准?

注意:我并不是在寻找在 DOM 中存储 JSON 的替代方案,我已经确定这是针对我遇到的特定问题的最佳解决方案。我只是在寻找最好的方法。

I'm thinking about embedding arbitrary JSON in the DOM like this:

<script type="application/json" id="stuff">
    {
        "unicorns": "awesome",
        "abc": [1, 2, 3]
    }
</script>

This is similar to the way one might store an arbitrary HTML template in the DOM for later use with a JavaScript template engine. In this case, we could later retrieve the JSON and parse it with:

var stuff = JSON.parse(document.getElementById('stuff').innerHTML);

This works, but is it the best way? Does this violate any best practice or standard?

Note: I'm not looking for alternatives to storing JSON in the DOM, I've already decided that's the best solution for the particular problem I'm having. I'm just looking for the best way to do it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

楠木可依 2025-01-13 09:08:44

我认为你原来的方法是最好的。 HTML5 规范甚至解决了这种用法:

“当用于包含数据块(而不是脚本)时,数据
必须内联嵌入,数据的格式必须使用给出
type 属性、src 属性不得指定,并且
脚本元素的内容必须符合要求
为所使用的格式定义。”

阅读此处: http://dev .w3.org/html5/spec/Overview.html#the-script-element

您已经这样做了,这有什么不值得喜欢的?如果您可以对属性数据进行格式化,则可以。它具有表现力,并且预期用途很明确。感觉不像是黑客(例如使用 CSS 来隐藏“载体”元素),这是完全有效的。

I think your original method is the best. The HTML5 spec even addresses this use:

"When used to include data blocks (as opposed to scripts), the data
must be embedded inline, the format of the data must be given using
the type attribute, the src attribute must not be specified, and the
contents of the script element must conform to the requirements
defined for the format used."

Read here: http://dev.w3.org/html5/spec/Overview.html#the-script-element

You've done exactly that. What is not to love? No character encoding as needed with attribute data. You can format it if you want. It's expressive and the intended use is clear. It doesn't feel like a hack (e.g. as using CSS to hide your "carrier" element does). It's perfectly valid.

韵柒 2025-01-13 09:08:44

作为一般方向,我会尝试使用 HTML5 数据属性。没有什么可以阻止您输入有效的 JSON。例如:

<div id="mydiv" data-unicorns='{"unicorns":"awesome", "abc":[1,2,3]}' class="hidden"></div>

如果您使用 jQuery,那么检索它就像以下一样简单:

var stuff = JSON.parse($('#mydiv').attr('data-unicorns'));

As a general direction, I would try using HTML5 data attributes instead. There's nothing to stop you putting in valid JSON. e.g.:

<div id="mydiv" data-unicorns='{"unicorns":"awesome", "abc":[1,2,3]}' class="hidden"></div>

If you're using jQuery, then retrieving it is as easy as:

var stuff = JSON.parse($('#mydiv').attr('data-unicorns'));
太阳公公是暖光 2025-01-13 09:08:44

这种在脚本标签中嵌入 json 的方法存在潜在的安全问题。假设 json 数据源自用户输入,则可以制作一个数据成员,该数据成员实际上会突破脚本标记并允许直接注入到 dom 中。请参阅此处:

http://jsfiddle.net/YmhZv/1/

这是注入,

<script type="application/json" id="stuff">
{
    "unicorns": "awesome",
    "abc": [1, 2, 3],
    "badentry": "blah </script><div id='baddiv'>I should not exist.</div><script type="application/json" id='stuff'> ",
}
</script>

没有办法逃脱/编码。

This method of embedding json in a script tag has a potential security issue. Assuming the json data originated from user input, it is possible to craft a data member that will in effect break out of the script tag and allow direct injection into the dom. See here:

http://jsfiddle.net/YmhZv/1/

Here is the injection

<script type="application/json" id="stuff">
{
    "unicorns": "awesome",
    "abc": [1, 2, 3],
    "badentry": "blah </script><div id='baddiv'>I should not exist.</div><script type="application/json" id='stuff'> ",
}
</script>

There is just no way around escaping/encoding.

随遇而安 2025-01-13 09:08:44

HTML5 包含 元素 用于保存机器可读的数据。作为

const jsonData = document.querySelector('.json-data');
const data = JSON.parse(jsonData.value);

console.log(data)
<data class="json-data" value='
  {
    "unicorns": "awesome",
    "abc": [1, 2, 3],
    "careful": "to escape ' quotes"
  }
'></data>

在这种情况下,如果您选择用双引号将值括起来,则需要将所有单引号替换为 '"。否则,您将面临 XSS 攻击的风险,就像其他答案所建议的那样。

HTML5 includes a <data> element for keeping machine readable data. As a—perhaps safer—alternative to <script type="application/json"> you could include your JSON data inside the value attribute of that element.

const jsonData = document.querySelector('.json-data');
const data = JSON.parse(jsonData.value);

console.log(data)
<data class="json-data" value='
  {
    "unicorns": "awesome",
    "abc": [1, 2, 3],
    "careful": "to escape ' quotes"
  }
'></data>

In this case you need to replace all single quotes with ' or with " if you opt to enclose the value with double quotes. Otherwise your risk XSS attacks like other answers have suggested.

夕嗳→ 2025-01-13 09:08:44

请参阅 OWASP 的 XSS 预防备忘单中的规则#3.1

假设您想在 HTML 中包含此 JSON:

{
    "html": "<script>alert(\"XSS!\");</script>"
}

在 HTML 中创建一个隐藏的

。接下来,通过编码不安全实体(例如,&、<、>、"、'、和、/)来转义 JSON,并将其放入元素内。

<div id="init_data" style="display:none">
        {"html":"<script>alert(\"XSS!\");</script>"}
</div>

现在您可以通过读取 textContent 并解析它:

var text = document.querySelector('#init_data').textContent;
var json = JSON.parse(text);
console.log(json); // {html: "<script>alert("XSS!");</script>"}

See Rule #3.1 in OWASP's XSS prevention cheat sheet.

Say you want to include this JSON in HTML:

{
    "html": "<script>alert(\"XSS!\");</script>"
}

Create a hidden <div> in HTML. Next, escape your JSON by encoding unsafe entities (e.g., &, <, >, ", ', and, /) and put it inside the element.

<div id="init_data" style="display:none">
        {"html":"<script>alert(\"XSS!\");</script>"}
</div>

Now you can access it by reading the textContent of the element using JavaScript and parsing it:

var text = document.querySelector('#init_data').textContent;
var json = JSON.parse(text);
console.log(json); // {html: "<script>alert("XSS!");</script>"}
百善笑为先 2025-01-13 09:08:44

我建议将 JSON 放入带有函数回调的内联脚本中(类似于 JSONP):

<script>
someCallback({
    "unicorns": "awesome",
    "abc": [1, 2, 3]
});
</script>

如果执行脚本是在文档之后加载,您可以将其存储在某处,可能带有附加标识符参数: someCallback("stuff", { ... });

I'd suggest to put JSON into an inline script with a function callback (kind of JSONP):

<script>
someCallback({
    "unicorns": "awesome",
    "abc": [1, 2, 3]
});
</script>

If the executing script is loaded after the document you can store this somewhere, possibly with an additional identifier argument: someCallback("stuff", { ... });

南风几经秋 2025-01-13 09:08:44

我的建议是将 JSON 数据保存在外部 .json 文件中,然后通过 Ajax 检索这些文件。您不会将 CSS 和 JavaScript 代码放入网页(内联),那么为什么要使用 JSON 呢?

My recommendation would be to keep JSON data in external .json files, and then retrieve those files via Ajax. You don't put CSS and JavaScript code onto the web-page (inline), so why would you do it with JSON?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文