情况:我正在撰写适用于任何网页的Chrome扩展程序。
问题:我无法将jQuery加载到Facebook中,我想了解发生了什么。
假设:Facebook拥有一些超级先进技术,以某种方式检测到两者:
DATA
我怎么知道jQuery没有加载?
我⌘ ⌥ j 在Chrome中调出控制台。当我这样做时:
> jQuery
>> ReferenceError : jQuery is not defined.
> $('body')
>> Error : Tried to get element "body" but it is not present on the page.
如何尝试在Facebook中加载jQuery?
方法1(必填但失败):
通过manifest.json文件中的以下代码:
"content_scripts" : [
{
"matches" : ["<all_urls>"],
"js" : [
"javascript/jq/jquery-1.9.1.min.js",
"javascript/jq/non-standard.js"
],
"all_frames": true // (or false, same failure)
}
]
方法2(有效,但不充分):
通过本SO答案(load jQuery into console)中描述的方法,修改为允许正确的协议:
var jq = document.createElement('script');
jq.src = "//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js";
document.getElementsByTagName('head')[0].appendChild(jq);
jQuery.noConflict();
摘要
假设1似乎不太可能,因为忽略Web浏览器的单独执行上下文将是一个主要的安全漏洞(打破沙箱),并且不太可能被制裁。因此,我可能是偏执狂,忽视了明显的,希望你们中的一个人会看到。
附录(其他相关代码)
所有 non-standard.js :
$.fn.in_groups_of = function( countPerGroup ) {
var groups = [], offset = 0, $group;
while ( ($group = this.slice( offset, (countPerGroup + offset) )).length ) {
groups.push( $group );
offset += countPerGroup;
}
return groups;
};
更多 manifest.json :
"manifest_version" : 2,
"permissions" : [
"http://*/",
"https://*/",
"tabs",
"storage",
"unlimitedStorage"
],
答案 0 :(得分:45)
Chrome控制台似乎无法访问内容脚本的执行上下文。
错了,确实如此。你需要看看正确的地方:
之前的截屏视频显示,Chrome开发者工具的控制台标签底部有两个下拉框,可用于更改开发人员工具控制台的执行环境。 左侧可用于更改帧上下文(顶部框架,因此iframe,...),右侧可用于更改脚本上下文(页面,内容脚本,...)。
答案 1 :(得分:2)
答案
看来我的“实验方法”存在缺陷。有关Chrome控制台无所不知的假设是不正确的。 Chrome控制台似乎无法访问内容脚本的执行上下文。因此虽然控制台报告说jQuery无法访问该页面,但它实际上是从内容脚本的执行上下文中进行的。
通过向manifest.json添加内容脚本test.js来验证这一点:
"content_scripts" : [
{
"matches" : ["<all_urls>"],
"js" : [
"javascript/jq/jquery-1.9.1.min.js",
"javascript/jq/non-standard.js",
"javascript/test.js" // <-- add
],
test.js的内容是:
var jtest = $('body');
alert(jtest);
alert(jtest.text());
现在无论我导航到哪个页面,都会按预期弹出两个警告框。
有效!
答案 2 :(得分:0)
你现在可能已经知道所有这些,但我认为有人仍然认为这些有用。
在Chrome扩展程序中
你有一些“脚本世界”:
Google在文档方面表现非常出色,因此大量文档都涉及所有这些脚本https://developer.chrome.com/extensions。
但在您的情况下,请注意:页面脚本和内容脚本位于不同的世界中,它们共享DOM和一些Chrome本机对象,但它们不共享它们创建的变量(或对象)。
对于这种情况,如果你的内容脚本中有jQuery,你可以在内容脚本中使用$和jQuery。您可以使用它来查询DOM(尽管某些jQuery事件可能无法按预期工作)。 但是在页面上,你不会有$和jQuery,(你可能有$,但它不是jQuery ^^)。
上面的方法2,它实际上将jQuery注入到页面中,jQuery将成为页面脚本。并且您不能在内容脚本中使用$或jQuery。
如果您同时使用这两种方法,您可以在页面脚本中使用jQuery 1,在内容脚本中使用jQuery 2,它们是2个不同的jQuery实例。这可能会引起混淆,但我一直这样做。