CKEditor 变量在控制台中可用,但在 Chrome 用户脚本中不可用?
我正在编写一个 Chrome 用户脚本,以便在 CKEditor 中本地自动保存内容。我使用这个 CKEditor 自动保存插件作为灵感。
我编写了一个每半秒触发一次的函数(通过一个时间间隔)来注册 CKEditor 事件处理程序:
var intervalId = window.setInterval(function() {
if (CKEDITOR) {
window.clearInterval(intervalId);
CKEDITOR.plugins.add("user-script-auto-save", {
init : function(editor) {
editor.on('key', startTimer);
}
});
}
}, 500);
但是,它永远不会正确完成,并抱怨 if 上的“CKEDITOR 未定义” (CKEDITOR) 声明。
同时,如果我进入 Chrome 的控制台并输入 CKEDITOR
,控制台会打印出预期的对象。
我缺少什么?编辑器嵌入在 iframe 中;这可能会对范围界定产生影响吗?或者我在这里与 Chrome 的沙箱作斗争?如果是这样,我是否可以通过其他方式深入 CKEditor 每秒提取内容或进行自动保存?
我还没有在 Firefox 中尝试过这个脚本;这是我名单上的下一个。
值得注意的是:我是一名长期的 JavaScript 新手。所以我很容易在范围界定或类似的事情上做一些愚蠢的事情。
I'm writing a Chrome userscript to locally auto-save content in a CKEditor. I'm using this CKEditor auto-save plugin as inspiration.
I have written a function that fires every half second (via an interval) to register the CKEditor
event handler:
var intervalId = window.setInterval(function() {
if (CKEDITOR) {
window.clearInterval(intervalId);
CKEDITOR.plugins.add("user-script-auto-save", {
init : function(editor) {
editor.on('key', startTimer);
}
});
}
}, 500);
However, it never properly completes, and complains that "CKEDITOR is undefined" on the if (CKEDITOR)
statement.
Meanwhile, if I drop into Chrome's console and type CKEDITOR
, the console prints out the expected object.
What am I missing? The editor is embedded within an iframe; might that have an impact on scoping? Or am I fighting against Chrome's sandboxing here? And if so, is there some other way I can dig into CKEditor to pull out the content every second or something to do the auto-saves?
I have not yet tried the script in Firefox; that's next on my list.
Worth noting: I'm a long-time JavaScript novice. So I could easily be doing something dumb with scoping or something like that.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
根据 YouTube 上的这个小教程视频,所有 3 个“设备”彼此分开其他是为了防止从用户脚本到浏览器/网站的 XSS 攻击,反之亦然。尽管用户脚本/内容脚本在网站上下文中运行,但它们仍然与实际网站脚本上下文分开。您可以通过简单地尝试从内容脚本访问例如 jQuery 来轻松确认这一点。就像 CKEditor 一样,它将不可用。
因此,为了解决这个问题,我想出了使用内容脚本在 head 标签中包含外部 JavaScript 的方法。 AFAIK,对于直接位于扩展根目录中的文件来说这是不可能的,所以我使用了远程服务器来托管我的文件。
我不确定这是否是最好的方法,我认为这是一个丑陋的旁路,可能是 Chromium 项目有时会增强和禁用的方法。
(由OP编辑,所以我可以选择这个答案并适当地路由业力)
这个答案,结合评论中的一些建议和链接,最终让我到达了我需要去的地方。
我最终得到了以下函数:
用法如下:
现在,我在 Chrome 扩展程序中执行此操作,但我怀疑该模式可能在通过 Chrome TamperMonkey 扩展程序部署的 GreaseMonkey 脚本中工作,前提是 URL要嵌入的脚本托管在可访问的地方。
FTR,事实证明,我实际上并不需要访问 iframe——CKEDITOR 变量是在顶级文档中定义的,但由于 Chrome 沙箱的规则
According to this little tutorial video on YouTube, all the 3 "devices" are separated from each other in order to prevent XSS attacks from the user script to the browser / website and vice versa. Although the user scripts / content scripts are running in the website's context, they are still kept separated from the actual website script context. You can easily acknowledge this by simply trying to access for example jQuery from a content script. Just as the CKEditor, it will not be available.
So what I've come up with in order to deal with this is using the content script to include external JavaScripts in the head tag. AFAIK, this is not possible for files directly in the extension's root directory, so I've taken a remote server to host my files.
I'm not sure if this is the best approach and I think it is an ugly bypass, possibly way to powerfull and disabled by the Chromium Project some time.
(Edited by OP, so I can select this answer and route karma appropriately)
This answer, combined with some of the suggestions and links in the comments, ended up getting me to where I needed to be.
I ended up with the following function:
Usage looks like so:
For now, I'm executing this from within a Chrome extension, but I suspect that the pattern might work in a GreaseMonkey script deployed via the Chrome TamperMonkey extension provided that the URL of the script to be embedded was hosted somewhere reachable.
FTR, as it turns out, I did not actually need to get to the iframe -- the CKEDITOR variable was defined in the top-level document, but was simply not visible because of the rules of the Chrome sandbox