微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在浏览器扩展上下文中通过TypeScript访问全局变量并在可能的情况下进行部分键入

如何解决如何在浏览器扩展上下文中通过TypeScript访问全局变量并在可能的情况下进行部分键入

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)?从第三方代码导入这种全局变量的正确方法是什么?

*:根据您尝试处理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. 使用tsc编译为JS。
  4. manifest.jsoncontent.js作为解压缩的浏览器扩展名导入浏览器。
  5. 加载random OGS game并进行检查。

解决方法

1。它的要旨

内容脚本无法直接访问全局变量,它们在“隔离的世界”中工作。来自Content Script Environment MDN Docs

但是,内容脚本获得了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键中使用的脚本。您也可以像*一样使用wildcards来同时匹配多个。

您可能仍需要将此内容添加到compilerOptionstsconfig.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.postMessagewindow.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,因此您只需要手动输入所需的类型即可...您可以检查类似Definitely Typed的内容,但是正如您提到的,如果他们还没有使用其代码/程序包发布任何公共存储库,那么您可能将找不到相应的内容。

编辑:要使打字稿不抱怨window变量,您可能需要添加更多类似内容:

type Goban = {
  bounded_height: number;
}

declare global {
   var goban: Goban;
}

详细了解以下内容:Declaring Global Variables

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。