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

IT技术 javascript json html script-tag
2021-01-14 06:27:02

我在服务器中生成了这个 JSON 文件,我想让它在客户端上可以访问,因为页面是可见的。基本上我想要实现的是:

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

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

其来源中引用的文件具有 JSON 数据。正如我所见,数据已下载,就像脚本中发生的一样。

现在,我如何在 Javascript 中访问它?我已经尝试使用 jQuery 和不使用 jQuery 访问脚本标记,使用多种方法来尝试获取我的 JSON 数据,但不知何故这不起作用。入门它innerHTML会工作了JSON数据被脚本编写的内联。它不是,也不是我想要实现的目标。

如果您想提出建议,则页面加载后的远程 JSON 请求也不是一种选择。

6个回答

你不能像那样加载 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 请求也不是一种选择。

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

好吧,您无法在客户端浏览器应用程序中真正向用户隐藏数据。他们可以直接进入浏览器的开发工具并在 JavaScript 中设置断点,然后以他们喜欢的方式检查对象。
2021-03-16 06:27:02
是的,整个挑战是使用脚本标签 src 属性加载它并在文档中“混淆”这些信息。
2021-03-20 06:27:02
很好的答案。当您说“脚本标签被‘滥用’”时,您的意思是脚本标签的使用是错误的(也许不是错误,而是“创造性的”)?你的 2 选项是我们已经在生产中使用的选项,我一直在寻找一种严格的 json/no-js 解决方案,出于纯实验(如果我确定它是不可能的,我很好)。关于最后一点,我在 onload 事件之前需要此信息,并且我不想使整个初始化依赖于异步请求,该请求的完成时间可能会有所不同。这是 Ajax 调用和脚本标记之间的主要区别。
2021-04-02 06:27:02
@Jaydipsinh,那么您需要解决 CORS 问题,并使用 Ajax。浏览器不允许这种行为是有原因的。大多数浏览器甚至不会再让您使用 iframe 绕过 CORS。
2021-04-07 06:27:02
不,我不认为这是“错误的”,可以说,只是……“创意”可能是一个好词。如果实际上可以将 JSON 写入<script>标签,我想我会走那条路。
2021-04-08 06:27:02

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

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

上面的例子使用了一个额外的 script 标签,类型为application/json一个更简单的解决方案是将 JSON 直接包含到 JavaScript 中:

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

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

+ 用于文本内容。.html 在脚本标签上对我不起作用
2021-03-30 06:27:02
在两者之间包含服务器端代码会降低代码module化和维护的可能性。
2021-03-30 06:27:02

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

HTML5 规范

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

似乎是处理比 JS 和 CSS 更敏感的数据的策略。
2021-03-13 06:27:02

虽然目前无法使用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>

要使用上述内容,只需将idandsrc属性替换为您需要的内容。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>

在 chrome 中测试,应该在 Firefox 中工作。不确定 IE 或 Safari。

我同意本。您无法加载/导入简单的 JSON 文件。

但是,如果您绝对想这样做并且可以灵活地更新 json 文件,则可以

我的-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>