英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论