在运行时加载 JSON 文件

Load JSON file at runtime

我有 HTML 个带有脚本的文件

<script src="tralBA.json" type="text/javascript"></script>

其中 tralBA.json:

var datiTral = {  
    "tral": 
    [
        {"trl_id": "BA_01", "longitude": 16.58, "latitude": 41.09},
        {"trl_id": "BA_02", "longitude": 16.578, "latitude": 41.112}, 
        {"trl_id": "BA_03", "longitude": 16.544, "latitude": 41.09}, 
        {"trl_id": "BA_04", "longitude": 16.556, "latitude": 41.08},        
        {"trl_id": "BA_05", "longitude": 16.580, "latitude": 41.085},       
        {"trl_id": "BA_06", "longitude": 16.590, "latitude": 41.096}
]}

和一个 JS 文件:

.......
var clusterTral = {};
clusterTral.tral = null;
clusterTral.tral = datiTral.tral; 

我 clusterTral.tral 完全受够了。

稍后我需要在运行时定义和使用我的 tralBA.json 文件。 我尝试通过以下功能来做到这一点

函数 showClusterTral(pv) {

var filename = "tral" + pv + ".json";
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('src', filename);
document.head.appendChild(script);  
clusterTral.tral = datiTral.tral;
.....

}

但我收到错误 "Uncaught ReferenceError: datiTral is not defined" 我该如何解决?谢谢。

问题的原因是当执行引用该值的代码时脚本标签仍在加载。这可以通过在调用脚本文件后立即引用加载变量的值来证明,并在一秒钟后再次引用(您可能需要改变配置中的超时值)。立即测试记录“[undefined]”,延迟日志显示 tral 对象的值。

function showClusterTral(pv) {

var filename = "tral" + pv + ".json";
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('src', filename);
document.head.appendChild(script);  
var clusterTral = {};
try {
    clusterTral.tral = datiTral.tral;
    console.log('Immeditate tral=' + JSON.stringify(clusterTral.tral))
    }
catch (err) {
    console.log('Immeditate tral=[not defined]')
    }
setTimeout(function(){
    clusterTral.tral = datiTral.tral;
    console.log('Delayed tral=' + JSON.stringify(clusterTral.tral))
    }, 1000)
}

showClusterTral("BA")  // kick off the function

换句话说,我们请求的脚本获取是异步的——JS 从下一行开始执行,而不等待脚本到达。答案将是某种类型的 ajax 请求。

注意:以这种方式加载脚本称为脚本注入,并且在 'JSONP' 旗帜下进行了大量讨论,用于克服同源策略。虽然在此样式中进行了跨域脚本注入 'can',但您应该考虑一些黑帽修改无辜者的风险您期望的源脚本。基本上不要注入您无法控制的脚本。

解决方案也是如此 - 快速阅读 Dave Walsh Blog on the subject 会得出以下答案。请注意,这需要 JQuery - 您没有指定这必须是纯 JS 解决方案,因此希望这对您可行:

function showClusterTral(pv) {

var clusterTral = {};

jQuery.getScript("tral" + pv + ".json")
    .done(function() {
        /* yay, all good, do something */
        clusterTral.tral = datiTral.tral;
        console.log('Delayed tral=' + JSON.stringify(clusterTral.tral))     
    })
    .fail(function() {
        /* boo, fall back to something else */
        console.log("Some error in the path maybe ?")   
});

}

showClusterTral("BA") // kick off the function

这里的区别在于,传递变量的使用现在取决于 getScript() 函数触发的 done 分支,这意味着我们不会从加载的脚本中引用变量,直到该文件在浏览器 JS 上下文中加载。还有一个 fail 处理程序,我们可以使用它来优雅地处理任何意味着脚本未加载的意外问题。

我无法将其添加为一个片段,因为它引用了一个外部文件,但如果你将上面的内容放入网页并保存 OP 定义的 tralBA.json 文件,那么一切都有效。