如何在浏览器扩展上下文中通过 TypeScript 访问全局变量(如果可能,部分输入)
How to Access a Global Variable through TypeScript in a Browser Extension Context (and partially type it if possible)
1。问题
我正在尝试通过 TypeScript 从网站访问全局变量 — random OGS Example — 以便从当前的棋盘游戏中获取数据。
我是 TS 的新手,所以我也不确定我将如何输入这个变量。 The global variable itself was originally created in TS actually,但它有无数的方法和属性,因为有这么多的功能。所以,如果我要自己打字,我宁愿只打我需要的东西,如果可能的话,或者以某种方式从某个地方的包中导入它——我认为作者没有在任何地方公开发布它。
与所有这些并行的是,还有一个问题,即默认情况下全局变量是否可用于浏览器扩展,which might not be the case。
2。我一直在尝试的
所以,我一直在尝试(我已经尝试了一百万种其他变体...)做的是类似* — 在 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
)?处理这种从第 3 方代码导入全局变量的正确方法是什么?
*:根据您尝试处理 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
文件。
- 用
tsc
编译成 JS。
- 将
manifest.json
和 content.js
作为解压缩的浏览器扩展导入浏览器。
- 加载 random OGS game 并检查它。
如果您在浏览器中在线打开控制台-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,所以你只需要手动编写你想要的类型......你可以检查 Definitely Typed 之类的东西,但正如你提到的,如果他们没有在 code/package 中发布任何 public 存储库,那么您可能找不到任何相关内容。
编辑:为了让打字稿不抱怨 window 变量,您可能需要添加更多类似的内容:
type Goban = {
bounded_height: number;
}
declare global {
var goban: Goban;
}
阅读更多关于:Declaring Global Variables
1。要点
内容脚本无法直接访问全局变量,它们在“孤立的世界”中工作。来自 Content Script Environment MDN Docs:
However, content scripts get a "clean" view of the DOM. This means:
- Content scripts cannot see JavaScript variables defined by page scripts.
但是您仍然可以通过 manifest.json
中的 web_accessible_resources
键共享资源来解决这个问题。
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
键中使用的脚本一样。您也可以使用 wildcards,如 *
,同时匹配多个。
You might still need to add this to your compilerOptions
inside your 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
与页面脚本通信。
更多资源:
1。问题
我正在尝试通过 TypeScript 从网站访问全局变量 — random OGS Example — 以便从当前的棋盘游戏中获取数据。
我是 TS 的新手,所以我也不确定我将如何输入这个变量。 The global variable itself was originally created in TS actually,但它有无数的方法和属性,因为有这么多的功能。所以,如果我要自己打字,我宁愿只打我需要的东西,如果可能的话,或者以某种方式从某个地方的包中导入它——我认为作者没有在任何地方公开发布它。
与所有这些并行的是,还有一个问题,即默认情况下全局变量是否可用于浏览器扩展,which might not be the case。
2。我一直在尝试的
所以,我一直在尝试(我已经尝试了一百万种其他变体...)做的是类似* — 在 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
)?处理这种从第 3 方代码导入全局变量的正确方法是什么?
*:根据您尝试处理 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
文件。 - 用
tsc
编译成 JS。 - 将
manifest.json
和content.js
作为解压缩的浏览器扩展导入浏览器。 - 加载 random OGS game 并检查它。
如果您在浏览器中在线打开控制台-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,所以你只需要手动编写你想要的类型......你可以检查 Definitely Typed 之类的东西,但正如你提到的,如果他们没有在 code/package 中发布任何 public 存储库,那么您可能找不到任何相关内容。
编辑:为了让打字稿不抱怨 window 变量,您可能需要添加更多类似的内容:
type Goban = {
bounded_height: number;
}
declare global {
var goban: Goban;
}
阅读更多关于:Declaring Global Variables
1。要点
内容脚本无法直接访问全局变量,它们在“孤立的世界”中工作。来自 Content Script Environment MDN Docs:
However, content scripts get a "clean" view of the DOM. This means:
- Content scripts cannot see JavaScript variables defined by page scripts.
但是您仍然可以通过 manifest.json
中的 web_accessible_resources
键共享资源来解决这个问题。
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
键中使用的脚本一样。您也可以使用 wildcards,如 *
,同时匹配多个。
You might still need to add this to your
compilerOptions
inside yourtsconfig.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
与页面脚本通信。
更多资源: