在版本 ≥4.0 中从浏览器扩展中访问 Ember.js 服务。

huangapple go评论76阅读模式
英文:

Accessing Ember.js services from browser extension in versions ≥4.0

问题

在Ember 4.0及更高版本中,访问Ember全局对象已被弃用。我们有一个用于内部调试/支持目的的浏览器插件,它会使用这个全局对象从一个Ember服务中收集一些变量,并生成一份文本报告,以便第一线支持人员在调查问题时使用。

以下是Ember 3.28的报告生成脚本的一部分。通常,这将通过使用 chrome.scripting.executeScript 方法注入到扩展中,使用world 'MAIN',但为了再现的目的,将其粘贴到控制台中将产生相同的效果。在Ember 4.0及更高版本中,这将抛出一个TypeError,因为window.Ember未定义。

var namespace = window.Ember.Namespace.NAMESPACES.find(ns => ns.name === 'acmecorp');
var sessionService = namespace.__container__.lookup('service:session');
var applicationAdapter = namespace.__container__.lookup('adapter:application');
var user = sessionService.get('user');
var userId = sessionService.get('user.id');
var userType = sessionService.get('user.type');
var userTypePath = applicationAdapter.pathForType(userType ?? 'user');

在升级到Ember 4.0及更高版本后,是否有一种方式可以从浏览器扩展中访问这些信息?

英文:

In Ember 4.0 and up, access to the Ember global object is deprecated. We have a browser plugin for internal debugging/support purposes that would gather some variables from an ember service using this global object and generate a text report that first-line support personel could use when investigating an issue.

Below is a part of the report generator script for Ember 3.28.
This will normally be injected by the extension using chrome.scripting.executeScript with world 'MAIN', but pasting in the console will have the same effect for reproduction purposes. In Ember 4.0 and up, this will throw a TypeError since window.Ember is undefined.

var namespace = window.Ember.Namespace.NAMESPACES.find(ns => ns.name === 'acmecorp');
var sessionService = namespace.__container__.lookup('service:session');
var applicationAdapter = namespace.__container__.lookup('adapter:application');
var user = sessionService.get('user');
var userId = sessionService.get('user.id');
var userType = sessionService.get('user.type');
var userTypePath = applicationAdapter.pathForType(userType ?? 'user');

Following our upgrade to Ember 4.0 and up, is there any way to access this information from a browser extension?

答案1

得分: 0

我在Ember Inspector init script中找到了一个临时答案:

const Ember = requireModule('ember')['default'];

如果您需要向后兼容,可以像Ember Inspector一样将其包装在try/catch块中:

let Ember;

try {
  Ember = requireModule('ember')['default'];
} catch {
  Ember = window.Ember;
}

请注意,这仅适用于将requireModule暴露给全局范围的Ember环境,通过window对象,对于其他应用程序/框架,不适用。另外,正如下面的NullVoxPopuli所指出的,这将在未来失效,因此,如果您能够更改源代码,更好的解决方案是自己将相关服务或变量暴露给window

英文:

I found a temporary answer in the Ember Inspector init script:

const Ember = requireModule('ember')['default'];

If you need to be backwards compatible, you can wrap it in a try/catch block like Ember Inspector does

let Ember;

try {
  Ember = requireModule('ember')['default'];
} catch {
  Ember = window.Ember;
}

Note that this only applies to Ember environment that expose requireModule to the global scope via the window object, for other applications/frameworks this does not apply. Also, as NullVoxPopuli notes below, this will break in the future so a better solution, if you are able to change the source, is to expose the relevant service or variables to window yourself.

huangapple
  • 本文由 发表于 2023年7月31日 20:39:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/76803722.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定