为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

jeck猫 2023-07-29 15:16:45
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 中开始的最简单方法是:创建一个简单的manifest.json,例如:{     "manifest_version": 2,     "name": "Name",     "version": "0.0.2",     "description": "Description.",     "content_scripts": [         {             "matches": ["*://*.online-go.com/*"],             "js": ["content.js"]         }     ]}content.ts使用上一节中的代码创建一个文件。编译为 JS 与tsc.将manifest.json和content.js作为解压的浏览器扩展导入到浏览器中。加载随机 OGS 游戏并检查它。
查看完整描述

2 回答

?
呼唤远方

TA贡献1856条经验 获得超11个赞

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": true

script.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

查看完整回答
反对 回复 2023-07-29
?
交互式爱情

TA贡献1712条经验 获得超3个赞

如果您在 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;

}

查看完整回答
反对 回复 2023-07-29
  • 2 回答
  • 0 关注
  • 152 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信