我正在使用基于Chrome的Firefox新的webExtensions框架编写webextension。所有示例扩展都在Nightly版本中工作,因此我可以在其中进行测试。我尝试做的是在加载时在内容页面上运行脚本。这是我的background.js页面:
background.js
final List<GbGroup> groups = this.businessService.getSiteSectionsAndGroups();
toolbar.add(new EmptyPanel("groupFilterOnlyOne").setVisible(false));
// add the default ALL group to the list
String allGroupsTitle = getString("groups.all");
groups.add(0, new GbGroup(null, allGroupsTitle, null, GbGroup.Type.ALL));
final DropDownChoice<GbGroup> groupFilter = new DropDownChoice<GbGroup>("groupFilter", new Model<GbGroup>(),
groups, new ChoiceRenderer<GbGroup>() {
private static final long serialVersionUID = 1L;
@Override
public Object getDisplayValue(final GbGroup g) {
return g.getTitle();
}
@Override
public String getIdValue(final GbGroup g, final int index) {
return g.getId();
}
});
groupFilter.add(new AjaxFormComponentUpdatingBehavior("onchange") {
@Override
protected void onUpdate(final AjaxRequestTarget target) {
final GbGroup selected = (GbGroup) groupFilter.getDefaultModelObject();
// store selected group (null ok)
final GradebookUiSettings settings = g_Page.getUiSettings();
settings.setGroupFilter(selected);
g_Page.setUiSettings(settings);
}
});
这适用于Nightly。我从后台页面获得了一系列详细信息(&#34;详细信息是......&#34;)以及几行&#34; ok&#34;在内容页面的控制台上,每个资源加载一个。它在Chrome中运行相同(清单文件略有不同)。
我想要的是第二种变体,它只在页面上运行一次。这在Chrome中运行良好。在Nightly中,它显示了一个&#34;细节&#34;来自主框架的消息,但内容页面上的控制台中没有任何内容。
我确定这是一个时间问题,但这里有什么问题?
manifest.json (删除&#34;应用&#34;:{...}与Chrome一起使用)
"use strict";
function onCompletedFunc(details) {
var script = 'console.log("ok");';
console.log("Details are %o", details);
chrome.tabs.executeScript(details['tabId'], {
code: script,
runAt: 'document_end'
});
};
chrome.webRequest.onCompleted.addListener(onCompletedFunc,
{'urls': ['<all_urls>']},
['responseHeaders']);
//Does not work:
/*
chrome.webRequest.onCompleted.addListener(onCompletedFunc,
{'urls': ['<all_urls>'], 'types':["main_frame"]},
['responseHeaders']);
*/
答案 0 :(得分:1)
您的第一个代码段(不包含types
)仅适用,因为您不仅要获取main_frame
的请求,还要获取另一个子资源。如果要注入脚本,webRequest.onCompleted
不是正确的事件。无法保证选项卡中的页面与您收到请求的页面匹配。
如果您想无条件地运行代码,只需在清单文件中声明内容脚本即可。有关详细信息,请参阅content script documentation。
如果必须使用编程注入,请使用chrome.webNavigation.onCommitted
事件而不是webRequest事件。通过此事件,您知道该选项卡现在显示对给定URL的响应。例如:
chrome.webNavigation.onCommitted.addListener(function(details) {
// Example: Only run in main frame and URLs containing "example"
if (details.frameId === 0 && details.url.includes('example')) {
chrome.tabs.executeScript(details.tabId, {
code: 'console.log("Injected at " + document.URL);',
runAt: 'document_end'
});
}
});
// filter (the second parameter, not used above) is supported as of Firefox 50.
如果您使用webNavigation.onCommitted
,必须考虑到API是非阻止的,则会发生事件。可能(但概率很低)发生以下情况:
webNavigation.onCompleted
开火。tabs.executeScript
。tabs.executeScript
请求到达选项卡,同时切换到不同的URL。如果不希望网址不匹配,请在继续使用内容脚本逻辑之前检查document.URL
或location
是否具有预期值。