HTML/Javascript: how to access JSON data loaded in a script tag with src set

我有这个 JSON 文件,我生成的服务器,我希望在客户端访问,因为页面是可见的。基本上,我想达到的目标是:

我在 html 文档中声明了以下标记:

<script id="test" type="application/json" src="http://myresources/stuf.json">

源文件中引用的文件包含 JSON 数据。正如我所看到的,数据已经被下载了,就像脚本一样。

现在,如何在 Javascript 中访问它?我尝试访问 script 标记,无论是否使用 jQuery,使用多种方法来获取 JSON 数据,但是不知为何这样做不起作用。如果 json 数据是在脚本中内联写入的,那么获得它的 innerHTML就会起作用。这不是我想要的,也不是我想要的。

在页面加载后远程 JSON 请求也不是一个选项,如果您想建议。

177944 次浏览

您不能像那样加载 JSON,对不起。

我知道你在想“为什么我不能在这里使用 src? 我见过这样的东西... ...”:

<script id="myJson" type="application/json">
{
name: 'Foo'
}
</script>


<script type="text/javascript">
$(function() {
var x = JSON.parse($('#myJson').html());
alert(x.name); //Foo
});
</script>

... 简单地说,那只是脚本标签作为数据持有者被“滥用”了。你可以用各种各样的数据做到这一点。例如,许多模板引擎利用脚本标记来保存模板

您有一个从远程文件加载 JSON 的简短选项列表:

  1. 使用 $.get('your.json')或其他类似的 AJAX 方法。
  2. 编写一个文件,设置一个全局变量到您的 json。
  3. 将其拉入一个不可见的 iframe 中,然后在加载后刮取其中的内容(我称之为“1997模式”)
  4. 咨询巫毒教牧师。

最后一点:

在页面加载后远程 JSON 请求也不是一个选项,如果您想建议。

这说不通啊。在处理 <script src="">时,AJAX 请求和浏览器发送的请求之间基本上没有什么区别。它们都将对资源执行 GET 操作。HTTP 不关心它是否因为脚本标记或 AJAX 调用而完成,服务器也不关心。

如果需要从另一个域加载 JSON: http://en.wikipedia.org/wiki/JSONP
然而,要注意潜在的 XSSI 攻击: Https://www.scip.ch/en/?labs.20160414

如果是同一个域,那么就使用 Ajax。

另一个解决方案是使用服务器端的脚本语言,并且只是内联地包含 json-data。下面是一个使用 PHP 的例子:

<script id="data" type="application/json"><?php include('stuff.json'); ?></script>
<script>
var jsonData = JSON.parse(document.getElementById('data').textContent)
</script>

上面的示例使用类型为 application/json的额外脚本标记。一个更简单的解决方案是将 JSON 直接包含到 JavaScript 中:

<script>var jsonData = <?php include('stuff.json');?>;</script>

带有额外标记的解决方案的优点是 JavaScript 代码和 JSON 数据彼此分离。

看来这是不可能的,或者至少不支持。

来自 HTML5规范:

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

检查这个答案: https://stackoverflow.com/a/7346598/1764509

$.getJSON("test.json", function(json) {
console.log(json); // this will show the info it in firebug console
});

在 javascript 中使用精确 json 的另一种选择。JSON 上,你可以直接使用 json 符号创建对象。如果将此存储在。Js 文件,您可以在应用程序中使用该对象。当我有一些静态 json 数据需要与应用程序的其他部分分开缓存在一个文件中时,这是一个非常有用的选项。

    //Just hard code json directly within JS
//here I create an object CLC that represents the json!
$scope.CLC = {
"ContentLayouts": [
{
"ContentLayoutID": 1,
"ContentLayoutTitle": "Right",
"ContentLayoutImageUrl": "/Wasabi/Common/gfx/layout/right.png",
"ContentLayoutIndex": 0,
"IsDefault": true
},
{
"ContentLayoutID": 2,
"ContentLayoutTitle": "Bottom",
"ContentLayoutImageUrl": "/Wasabi/Common/gfx/layout/bottom.png",
"ContentLayoutIndex": 1,
"IsDefault": false
},
{
"ContentLayoutID": 3,
"ContentLayoutTitle": "Top",
"ContentLayoutImageUrl": "/Wasabi/Common/gfx/layout/top.png",
"ContentLayoutIndex": 2,
"IsDefault": false
}
]
};

虽然目前使用 script标记是不可能的,但是如果 iframe来自同一个域,那么使用它是可能的。

<iframe
id="mySpecialId"
src="/my/link/to/some.json"
onload="(()=>{if(!window.jsonData){window.jsonData={}}try{window.jsonData[this.id]=JSON.parse(this.contentWindow.document.body.textContent.trim())}catch(e){console.warn(e)}this.remove();})();"
onerror="((err)=>console.warn(err))();"
style="display: none;"
></iframe>

要使用上面的代码,只需将 idsrc属性替换为您需要的属性。id(在这种情况下我们假设它等于 mySpecialId)将用于在 window.jsonData["mySpecialId"]中存储 data

换句话说,对于每个具有 id并使用 onload脚本的 iframe,都会将该数据 synchronously加载到指定的 id下的 window.jsonData对象中。

我这样做是为了好玩,并表明它是“可能的”,但我做 没有建议使用。


下面是一个使用回调的替代方法。

<script>
function someCallback(data){
/** do something with data */
console.log(data);


}
function jsonOnLoad(callback){
const raw = this.contentWindow.document.body.textContent.trim();
try {
const data = JSON.parse(raw);
/** do something with data */
callback(data);
}catch(e){
console.warn(e.message);
}
this.remove();
}
</script>
<!-- I frame with src pointing to json file on server, onload we apply "this" to have the iframe context, display none as we don't want to show the iframe -->
<iframe src="your/link/to/some.json" onload="jsonOnLoad.apply(this, someCallback)" style="display: none;"></iframe>

测试的铬和应该在火狐工作。不确定 IE 或 Safari。

我同意 Ben 的观点,你不能加载/导入简单的 JSON 文件。

但是,如果您确实希望这样做,并且具有更新 json 文件的灵活性,那么可以这样做

My-json js

   var myJSON = {
id: "12ws",
name: "smith"
}

Html

<head>
<script src="my-json.js"></script>
</head>
<body onload="document.getElementById('json-holder').innerHTML = JSON.stringify(myJSON);">
<div id="json-holder"></div>
</body>

place something like this in your script file json-content.js

var mainjson = { your json data}

然后从脚本标记调用它

<script src="json-content.js"></script>

然后你可以在下一个脚本中使用它

<script>
console.log(mainjson)
</script>

虽然不受支持,但是有一个通用的替代方案可以让 json 进入 javascript。您声明“ Remote json request”不是一个选项,但是您可能希望考虑它,因为它可能是最好的解决方案。
如果支持 src 属性,那么它将执行一个远程 json 请求,所以我不明白为什么要避免这种情况,而主动寻求以几乎相同的方式执行。

解决方案:

<script>
async function loadJson(){
const res = await fetch('content.json');
const json = await res.json();
}
loadJson();
</script>

Advantages

  • allows caching, make sure your hosting/server sets that up properly
  • 在 chrome 上,在使用性能选项卡进行分析之后,我注意到与内联 JS、内联 JSON 和外部 JS 相比,它的 CPU 占用最小。