我们可以在浏览器会话中跨网页引用 JavaScript 变量吗?

IT技术 javascript html extern
2021-01-15 03:59:24

通过w3schools的 JavaScript教程,发现以下语句:

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

所以,我的问题是,我们是否有办法引用在特定网页中声明的变量?

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

例如:

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

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

6个回答

你可以使用Web Workers; MessageChannel,请参阅如何从另一个 iFrame 清除 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();
}
@a3.14_Infinityfile:在铬的协议和 plnkr 上都尝试过您正在尝试使用哪个浏览器js
2021-03-15 03:59:24
@ guest271314 仅当一页被另一页框住时。从 OP 中不清楚是否涉及框架,并且链接的 W3C 页面也不建议这样做。如果想法是浏览器访问page1,然后page2,page2希望访问page1定义的全局变量,答案是不可能的。page1 脚本不再存在于内存中,也不存在于 JS 解释器中。完成该任务的唯一方法是让 page1 将数据编组为字符串并将其存储在 cookie 或 LocalStorage 中,在页面卸载之前将其显式传递
2021-03-25 03:59:24
我相信这些技术只适用于跨框架边界,而不适用于顶层的导航操作。
2021-03-26 03:59:24
@guest271314:看起来很有趣。我尝试在本地运行该示例,但出现错误:Uncaught SecurityError: Failed to build 'SharedWorker': (failure is发生在 scriptB.js ) worker.js 无法从原点 'null' 访问。我错过了什么吗?
2021-04-06 03:59:24
@Tom 给出了 OP 文件的描述,如果文件在同一个域中,应该能够xfileA.htmlfileB.html
2021-04-11 03:59:24

哈哈,不。 ;)

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

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

@epascarello 我尝试使用 jqueryUI 和 bootstrap,两者都会影响 Page2 中的 UI 元素。我对此很困惑,我在哪里可以得到澄清?
2021-03-14 03:59:24
你为什么笑?他不是在开玩笑,而是在问一个真正的问题,为什么要光顾答案?
2021-03-21 03:59:24
因此,如果我在一页中Page1.html包含 Jquery 而在Page2.html. 现在我从 page1 导航到 page2,jquery 可以在 page2 中使用(或它有效果)吗?
2021-03-22 03:59:24
如果你没有包括它,我怀疑 jquery 在第 2 页上工作。
2021-04-13 03:59:24

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

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

您可以通过 cookie 执行您所说的操作(在网页之间传递值)。它们存储在用户计算机上并且不会被销毁,除非明确销毁或过期。

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

MDN

W3学校