【问题标题】:Can we refer to JavaScript variables across webpages in a browser session?我们可以在浏览器会话中跨网页引用 JavaScript 变量吗?
【发布时间】:2016-07-08 21:07:22
【问题描述】:

通过 w3schools tutorial 获取 JavaScript,找到以下语句:

全局变量具有全局范围:网页上的所有脚本和函数都可以访问它。

那么,我的问题是,我们有办法引用在特定网页中声明的变量吗?

例如,在 C 语言中,我们有 extern 关键字,使用它我们可以访问在另一个文件中声明的变量,但我们可以在我们的文件中引用它。

例如:

在fileA.html的script标签里面,我们声明了var x = 50,在function()声明之外,所以它是全局w.r.t fileA.html。 如果我有fileB.html,我们可以在fileB.html 中包含的脚本标签中引用x 吗?

需要明确的是,这不是跨网页重用 JavaScript 文件的场景。

【问题讨论】:

  • JavaScript 全局变量相对于包含的全局上下文是“全局的”(它们只是所述上下文的属性) - 在浏览器中,它是 Window 对象,每个页面都是不同的 -在每次重新加载或导航时加载并销毁/重新创建。每个 IFRAME 还将建立自己的 Window 上下文,尽管有一些规则可以跨越。
  • 请尽快戒掉w3schools,它充满了错误。
  • @RobG,我要去 MDN 教程 -> developer.mozilla.org/en-US/docs/Web/JavaScript
  • @a3.14_Infinity 查看更新后的帖子;包括一种利用SharedWorkerdeveloper.mozilla.org/en-US/docs/Web/API/SharedWorker的方法

标签: javascript html extern


【解决方案1】:

你可以使用Web WorkersMessageChannel,见How to clear the contents of an iFrame from another iFrame;或window.postMessage() 在浏览上下文之间通信或传递变量。


一种利用SharedWorker的方法

fileA.html

<!DOCTYPE html>
<html>
  <head>
    <script src="scriptA.js"></script>
  </head>
  <body>
    <a href="fileB.html" target="_blank">fileB</a>
  </body>
</html>

scriptA.js

var x = 50, p;

var worker = new SharedWorker("worker.js");

worker.port.addEventListener("message", function(e) {
  alert(e.data);
  if (!p) {
    p = document.createElement("p");
    p.innerHTML = e.data;
    document.body.appendChild(p)
  }
}, false);

worker.port.start();

console.log("Calling the worker from fileA")

worker.port.postMessage(x); // post `50` to worker

fileB.html

<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="style.css">
    <script src="scriptB.js"></script>
  </head>
  <body>
  </body>
</html>

scriptB.js

var x, p;
var worker = new SharedWorker("worker.js");
worker.port.addEventListener("message", function(e) {  
  if (!x && !p) {
    x = e.data; // at `connections`:`1` : `e.data`:`50`
    p = document.createElement("p");
    p.innerHTML = "Message from fileA:" + x;
    document.body.appendChild(p)
  }
}, false);  
worker.port.start();  
console.log("Calling the worker from fileB");
worker.port.postMessage("");

worker.js

self.x = null, connections = 0;

onconnect = function(e) {
  var port = e.ports[0];
  ++connections;
  port.addEventListener("message", function(e) {
    if (!self.x) {
      self.x = e.data;
      port.postMessage("Received:" + self.x 
                       + " from fileA, total connections:" 
                       + connections);
    } else {
      port.postMessage("fileB received:" + self.x 
                       + " total connections:" 
                       + connections);
    }
  });
  port.start();
}

【讨论】:

  • 我相信这些技术只适用于框架边界,而不适用于顶层的导航操作。
  • @Tom 给定 OP 文件的描述,如果文件在同一个域中,应该能够将 xfileA.html 传递到 fileB.html
  • @guest271314 仅当一页被另一页框住时。 OP 不清楚是否涉及框架,链接的 W3C 页面也没有表明这一点。如果想法是浏览器访问page1,然后page2,而page2希望访问page1定义的全局变量,答案是不可能的。 page1 脚本不再在内存中,也不存在于 JS 解释器中。完成任务的唯一方法是让 page1 将数据编组为字符串并将其存储在 cookie 或 LocalStorage 中,在页面卸载之前显式传递它
  • @guest271314:看起来很有趣。我尝试在本地运行示例,但出现错误:Uncaught SecurityError: Failed to construction 'SharedWorker': (failure is occurred in scriptB.js) worker.js cannot be access from origin 'null'。我错过了什么吗?
  • @a3.14_Infinity 在file: 协议和铬的 plnkr 上都试过了。您在尝试js 哪个浏览器?
【解决方案2】:

是的,有点“可能”,有一个概念叫ever cookie,即使你从一个浏览器换到另一个浏览器,它的意图是不惜一切代价坚持一个cookie,这个想法是存储在任何可用的存储机制中浏览器(本地存储、cookie、flash cookie、indexDB 等)数据。因此,如果其中一个存储发生故障,cookie 会从一个位置复制到另一个位置,因此同时一个存储还存在 cookie 数据,这将一直存在。如果用户拥有Flash Local Shared Object cookie

,则跨浏览器支持可能会起作用

来源:http://samy.pl/evercookie/

说:我认为使用这种方法不是一个好主意,也许一个简单的localStorage['myvariable'] = {data:"data"} 就足够了。

【讨论】:

    【解决方案3】:

    您可以使用 LocalStorage 和 Session Storage 来实现相同的目的。

    MDN

    W3Schools

    【讨论】:

      【解决方案4】:

      “全局”是指在声明它们的特定脚本中的全局。一旦脚本完成执行,它们就会与除 cookie 之外的所有其他变量一起被销毁。

      您可以通过 cookie 做您所说的事情(在网页之间传递值)。它们存储在用户计算机上,除非明确销毁或过期,否则不会被销毁。

      【讨论】:

        【解决方案5】:

        如果您的网页在同一个 DOMAIN 中,它们可以共享一个 localStorage。您可以将字符串存储在 localStorage 中,并将它们加载到准备好的文档中。但是,您需要自己处理并发/读写问题。

        【讨论】:

          【解决方案6】:

          哈哈,号;)

          当浏览器离开一个页面时,全局范围和所有脚本在加载下一页之前完全卸载。

          允许一个页面访问另一个页面的变量将是一个巨大的安全漏洞。

          【讨论】:

          • 因此,如果我在一页 Page1.html 中包含 Jquery 而在 Page2.html 中不包含 Jquery。现在我从page1导航到page2,jquery可以在page2中使用(或者它有效果)吗?
          • @epascarello 我尝试使用 jqueryUI 和 bootstrap,两者都会影响 Page2 中的 UI 元素。我对此感到非常困惑,我在哪里可以得到澄清?
          • 如果你没有包含它,我怀疑 jquery 在第 2 页上是否有效。
          • 你为什么大声笑?他不是在开玩笑,而是在问一个真正的问题,为什么要光顾一个答案?
          猜你喜欢
          • 1970-01-01
          • 2019-10-03
          • 1970-01-01
          • 2010-12-25
          • 2013-08-12
          • 2014-12-24
          • 2011-07-03
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多