【问题标题】:how to fetch a javascript file content and parse it to use it's variables如何获取 javascript 文件内容并解析它以使用它的变量
【发布时间】:2019-03-14 14:21:55
【问题描述】:

我正在尝试获取这个 javascript 文件

https://eloquentjavascript.net/code/journal.js

通过使用原生 fetch 命令,如

fetch('https://eloquentjavascript.net/code/journal.js').then(v => {
  //do something here
})

如果上面的 journal.js 在其中声明了一个变量 - 我如何在当前范围内使用该变量。

如果我 console.log(v) - 那么就无法访问该变量 - 因为 chrome 显示:

有没有办法获取一个 javascript 文件(作为文本)然后解析它,以便我们可以在我当前的范围内使用导入文件的对象和方法??

该文件的内容声明了一个变量,如:

var JOURNAL = [{"events":["carrot","exercise","weekend"],"squirrel":false},{"events":["bread","pudding","brushed teeth","weekend","touched tree"],"squirrel":false}]

【问题讨论】:

  • 您是否试图避免只使用<script> 标签?
  • 如果您担心在您的环境中注入外部 JS 代码的安全性,请注意您可以使用工作人员(或沙箱)对其进行解析,并仅返回数据
  • 您能否编辑您的问题以阐明您所针对的环境?您说您正在使用 Node.js,但您也说您正在使用本机 fetch(Node.js 中不存在)并且您已经显示了 Chrome 的日志输出。您是要在浏览器中还是在 Node.js 中获取这些数据?
  • 是的 - 抱歉 - 不是 nodeJS - 但作为将在浏览器中运行的单个 javascript 文件

标签: javascript parsing fetch


【解决方案1】:

使用eval:

fetch('https://eloquentjavascript.net/code/journal.js').then(v => {
  v.text().then(txt => {
    eval(txt)
    console.log(JOURNAL)
  })
})

【讨论】:

  • 是的,这有效 - 但仅在禁用 CORS 策略的情况下 - 从新的 google chrome 选项卡 - 我收到 CORS 错误 - 但它在其他域中运行良好
  • CORS 是你应该在服务器端处理的东西。添加HTTP头Access-Control-Allow-Origin: *
  • @Avraham 不错的答案,正如@Probosckie 提到的,我添加了一些关于 CORS 的 fetch() API 选项。你确定console.log(JOURNAL) 会起作用吗?重新生成时收到错误消息:“JOURNAL 未定义”
  • @JürgenFink 如果您的journal.js 文件声明了JOURNAL 变量,它应该可以工作。尝试console.log(txt) 以确保您获得预期的内容。
  • @Avraham 是的,我也是这么想的。如果您想查看和评论,我已经发布了关于 CORSfetch() here 的更详细的答案。不过,您在这里的回答非常有帮助。我将它用于我自己的项目(同源) - 就像一个魅力 ? 谢谢。
【解决方案2】:

你不需要解析任何东西,你也可以模拟脚本需要的变量和函数,然后让浏览器评估脚本。

// The script will try to access global in your current environnement
// So we define it and add it to our scope
let wrapped = window.global = {};

// Add the script to the page
$.getScript("https://eloquentjavascript.net/code/journal.js", function(){
  // wrapped now contains the wanted data !
  document.write(JSON.stringify(wrapped));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

没有 jQuery 的替代方案:

function getScript(source, callback) {
    var script = document.createElement('script');
    var prior = document.getElementsByTagName('script')[0];
    script.async = 1;

    script.onload = script.onreadystatechange = function( _, isAbort ) {
        if(isAbort || !script.readyState || /loaded|complete/.test(script.readyState) ) {
            script.onload = script.onreadystatechange = null;
            script = undefined;

            if(!isAbort) { if(callback) callback(); }
        }
    };

    script.src = source;
    prior.parentNode.insertBefore(script, prior);
}

【讨论】:

  • $.getScript 是一个 jQuery 函数; OP 没有表示他们正在使用 jQuery。
  • 是的,但是 OP 可以找到很多其他帖子来解释如何在没有 jQuery 的情况下做到这一点
【解决方案3】:

使用承诺:

作为@Vinz243 和@Avraham 答案的替代解决方案。

function loadScript(src) {
  return new Promise((resolve, reject) => {
    let script  = document.createElement('script');
    script .type = 'text/javascript';
    script.charset = 'utf-8';
    script.async = true;
    script.src = src;
    script.onload = function () {
      resolve(script);
      document.getElementById('status').innerHTML = 'https://eloquentjavascript.net/code/journal.js loaded';

      // now you have access to the variable 'JOURNAL' (is an array of objects)
      console.log(JOURNAL);
      document.getElementById('events_01').innerHTML = '1: ' + JOURNAL[0].events;
      document.getElementById('events_02').innerHTML = '2: ' + JOURNAL[1].events;
    };
    script.onerror = function () {
      reject(new Error(`Script load error for ${src}`))
    };
    document.body.appendChild(script);
  })
};

loadScript('https://eloquentjavascript.net/code/journal.js');
<div id='status'>please wait <br><br>Trying to load file ...</div>
<br><hr>

<div id='events_01'>loading ...</div>
<div id='events_02'>loading ...</div>

注意:
@Avraham 的解决方案非常优雅,我成功地将它用于我项目中的其他 js 文件。
但是,在这种特殊情况下,我无法在复制他的解决方案时访问变量 JOURNAL,这是最初问题的一部分。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-10-17
    • 2021-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-10
    相关资源
    最近更新 更多