HTML/Javascript:如何使用src set访问脚本标记中加载的JSON数据

Chu*_*ckE 82 html javascript html5 json script-tag

我有我在服务器上生成的JSON文件,因为页面是可见的,所以我想在客户端上访问它.基本上我想要实现的是:

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

<script id="test" type="application/json" src="http://myresources/stuf.json">
Run Code Online (Sandbox Code Playgroud)

源中引用的文件具有JSON数据.正如我所见,数据已经下载,就像脚本一样.

现在,我如何在Javascript中访问它?我已经尝试使用和不使用jQuery访问脚本标记,使用多种方法来尝试获取我的JSON数据,但不知怎的,这不起作用.innerHTML如果json数据是在脚本中内联编写的,那么它本来可行.它不是,而不是我想要实现的目标.

页面加载后的远程JSON请求也不是一个选项,以防您想要建议.

Ben*_*esh 105

你不能这样加载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>
Run Code Online (Sandbox Code Playgroud)

......简而言之,就是脚本标签被"滥用"为数据持有者.你可以用各种数据做到这一点.例如,许多模板引擎利用脚本标记来保存模板.

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

  1. 使用$.get('your.json')或其他一些这样的AJAX方法.
  2. 编写一个将全局变量设置为json的文件.(好像很好).
  3. 将它拉入一个不可见的iframe,然后在它加载后刮掉它的内容(我称之为"1997模式")
  4. 咨询伏都教牧师.

最后一点:

页面加载后的远程JSON请求也不是一个选项,以防您想要建议.

......这没有意义.在处理您的浏览器时,AJAX请求与浏览器发送的请求之间的区别<script src="">基本上没有.他们都将对资源进行GET.HTTP不关心是否由于脚本标记或AJAX调用而完成,您的服务器也不会.

  • 很好的答案.当你说"脚本标签被'滥用'"时,你的意思是使用脚本标签是错误的(可能没有错,但"有创意")?你的 2选项是我们已经在生产中的选项,我正在寻找一个严格的json/no-js解决方案,纯粹的实验(我很好,如果我确定它是不可能的).关于最后一点,我在onload事件之前需要这个信息,我不想让整个初始化依赖于异步请求,这可能会在完成时间上有所不同.这是Ajax调用和脚本标记之间的关键区别. (5认同)

Lea*_*ema 11

另一种解决方案是使用服务器端脚本语言并简单地包含内联的json数据.这是一个使用PHP的示例:

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

上面的示例使用带有类型的额外脚本标记application/json.更简单的解决方案是将JSON直接包含在JavaScript中:

<script>var jsonData = <?php include('stuff.json');?>;</script>
Run Code Online (Sandbox Code Playgroud)

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


btx*_*000 8

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

HTML5规范:

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


hos*_*ian 6

在您的脚本文件中放置类似的内容 json-content.js

var mainjson = { your json data}
Run Code Online (Sandbox Code Playgroud)

然后从脚本标签调用它

<script src="json-content.js"></script>
Run Code Online (Sandbox Code Playgroud)

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

<script>
console.log(mainjson)
</script>
Run Code Online (Sandbox Code Playgroud)


kem*_*ica 5

虽然目前无法使用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>
Run Code Online (Sandbox Code Playgroud)

要使用以上内容,只需将idand src属性替换为所需的内容。在id(我们将在这种情况下,假定等于mySpecialId)将被用于存储数据window.jsonData["mySpecialId"]

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

我这样做是出于娱乐目的,并表明它是“可能的”,但我建议您使用它。


这是使用回调的替代方法。

<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>
Run Code Online (Sandbox Code Playgroud)

经过镀铬测试,可以在Firefox中使用。不确定IE或Safari。