如何在浏览器扩展上下文中通过 TypeScript 访问全局变量

1. 问题

我正在尝试通过 TypeScript 从网站(随机 OGS 示例)访问全局变量,以便从当前棋盘游戏获取数据。

我对 TS 还很陌生,所以我也不确定如何输入这个变量。全局变量本身实际上最初是在 TS 中创建的,但它具有无数的方法和属性,因为有如此多的功能。因此,如果我要自己输入它,我宁愿只输入我需要的内容(如果可能的话),或者以某种方式从某个包中导入它 - 我认为作者没有在任何地方公开发布它。

与此同时,还有一个问题是全局变量是否默认可用于浏览器扩展,但情况可能并非如此。

2.我一直在尝试的事情

所以,我一直在尝试(我已经尝试过一百万个其他变体......)做的是类似 * - inside content.ts,它在OGS域内运行 -:

interface Goban {

  bounded_height: number;

}


declare var goban: Goban;


goban = window["global_goban"];


console.log(goban.bounded_height.toString());

我通常得到的错误是:

Uncaught ReferenceError: goban is not defined

那么我错过了什么?我必须创建声明文件 ( .d.ts) 吗?处理这种从第三方代码导入全局变量的正确方法是什么?

*:根据您尝试处理window对象的方式,您可能必须添加"suppressImplicitAnyIndexErrors": true到您的对象中tsconfig.json,以便 TS 不会静态地抱怨。

3. 如何完全重现我的问题

对于那些不熟悉如何开发浏览器扩展的人来说,在 TS 中开始的最简单方法是:

  1. 创建一个简单的manifest.json,例如:

    {
        "manifest_version": 2,
        "name": "Name",
        "version": "0.0.2",
        "description": "Description.",
        "content_scripts": [
            {
                "matches": ["*://*.online-go.com/*"],
                "js": ["content.js"]
            }
        ]}
  2. content.ts使用上一节中的代码创建一个文件。

  3. 编译为 JS 与tsc.

  4. manifest.jsoncontent.js作为解压的浏览器扩展导入到浏览器中。

  5. 加载随机 OGS 游戏并检查它。


jeck猫
浏览 192回答 2
2回答

呼唤远方

1. 要点内容脚本无法直接访问全局变量,它们在“隔离的世界”中工作。然而,内容脚本可以获得 DOM 的“干净”视图。这意味着:内容脚本无法看到页面脚本定义的 JavaScript 变量。web_accessible_resources但您仍然可以通过manifest.json.2. 一种可能的解决方法这是实现此目的的一种方法:manifest.json:{  "manifest_version": 2,  "name": "Name",  "version": "0.0.2",  "description": "Description.",  "content_scripts": [    {      "matches": ["*://*.online-go.com/*"],      "js": ["content.js"]    }  ],  "web_accessible_resources": ["script.js"]}您可以将您可能需要的任何脚本添加到密钥中,就像上面密钥web_accessible_resources中使用的脚本一样。matches您还可以使用通配符(例如 )*同时匹配多个。您可能仍然需要将其添加到您的:compilerOptions内部。tsconfig.json"suppressImplicitAnyIndexErrors": truescript.ts:interface Goban {  bounded_height: number;}declare var goban: Goban;goban = window['global_goban'];console.log(goban.bounded_height.toString());content.ts:const script = document.createElement('script');script.src = chrome.extension.getURL('script.js');document.head.append(script);@types/chrome例如,您可能还需要通过npm i --save @types/chrome.3. 更多资源window.postMessage此外,内容脚本可以使用和与页面脚本进行通信window.addEventListener。

交互式爱情

如果您在 online-go.com 上的浏览器中打开控制台,您可以输入goban并看到它是全局可用的,就像这样。因此,window.goban这将是访问变量的方式。我会做类似的事情:interface Goban {  bounded_height: number;}const local_goban: Goban = window.goban;console.log(local_goban.bounded_height.toString());要不就interface Goban {  bounded_height: number;}const goban: Goban = window.goban;console.log(goban.bounded_height.toString());在您定义的代码中global_goban,但随后继续访问goban. 确保变量名称一致。至于自动从该页面输入全局变量,我认为这实际上是不可能的。Typescript 不能在浏览器中工作,它总是必须编译为普通的 JS,所以你只需要手动编写你想要的类型......你可以检查像 Definely Typed 这样的东西,但正如你提到的,如果他们没有没有发布任何公共存储库及其代码/包,那么您可能无法找到任何内容。编辑:为了让打字稿不抱怨窗口变量,您可能需要添加更多类似的内容:type Goban = {  bounded_height: number;}declare global {   var goban: Goban;}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript