Javascript 内容脚本不';不要在每次加载页面时都被注入
我在我的Javascript 内容脚本不';不要在每次加载页面时都被注入,javascript,google-chrome-extension,Javascript,Google Chrome Extension,我在我的manifest.json文件中有一个基本内容脚本,我让它匹配某个URL并加载脚本 "content_scripts": [ { "matches": ["http://www.urlhere.com/videos/*"], "js": ["scripts/jquery-2.1.1.min.js", "scripts/csScript.js"] } ], csScript.js获取页面上的属性,并通过消息将其发送回background.j
manifest.json
文件中有一个基本内容脚本,我让它匹配某个URL并加载脚本
"content_scripts": [
{
"matches": ["http://www.urlhere.com/videos/*"],
"js": ["scripts/jquery-2.1.1.min.js", "scripts/csScript.js"]
}
],
csScript.js
获取页面上的属性,并通过消息将其发送回background.js
脚本
chrome.runtime.sendMessage({url: getUrl()});
function getUrl() {
url = $('meta[itemprop=contentURL]').attr('content');
return url;
}
background.js
页面获取带有属性值的消息,对其进行操作,然后显示page\u action
图标
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
url = manipulateUrl(request.url);
chrome.pageAction.show(sender.tab.id);
});
chrome.pageAction.onClicked.addListener(function(tab) {
console.log("url: " + url);
});
在第一次页面加载时,所有这些都可以很好地工作——执行内容脚本并传递消息。但是,该页面有指向其他视频的链接……当我单击其中一个视频时,我注意到Chrome微调器在地址栏中加载了一个新的URL,但内容脚本不会再次执行
当我单击我的page\u action
图标时,我得到了传递的旧URL,这表明内容脚本没有得到页面的新URL
有什么想法吗?URL可能通过历史操作或URL片段更改而更改,但实际上不会重新加载页面 如果是URL片段更改,您可以使用
window.onhashchange
event
如果URL完全更改但页面未重新加载,则可能是通过history.pushState
或history.replaceState
函数实现的。不幸的是,它们不会触发任何事件。因此,它很难被发现
黑客的解决方案是在页面的上下文中插入页面,这样它也可以从内容脚本中检测到一些东西。它可以是DOM更改、自定义事件或窗口.postMessage
调用
编辑:从a开始,一个更好的解决方案是收听
chrome.webNavigation.onHistoryStateUpdated
(归功于joshft91)只是偶然,但您确定单击链接时的新URL也与该字符串匹配吗?它可能会删除http
,或者变成https
?几乎可以肯定它没有改变https
从未在任何视频页面上显示,因此我认为这不是问题所在。我想,DOM中必须保持一致,才能使内容脚本不再被注入,但我对扩展开发太陌生了。我还尝试了编程注入
在单击页面图标
时注入脚本,但同样的问题也发生了-我从“旧”DOM中获取旧url数据。是一个全新的url,还是只是哈希部分(window.location.hash)发生了变化?肯定是一个新的url。如果我回到主页,然后点击一个视频,效果很好。但在视频结束后,我会得到一个建议视频的列表——如果我单击其中一个,微调器会旋转并加载一个新的URL,但不会插入内容脚本。对我来说没有太多意义。可能类似的情况:有没有好的方法来判断这是否是一个片段更改?如果是这样的话,我也不会感到惊讶,因为除了最后一个片段,也就是标题,一切都是一样的。然而,Chrome旋转器正在旋转,所以我假设它正在加载一个新页面。我会看看你的解决方案,看看我能不能找到有效的方法。谢谢。请查看发生时是否触发了window.onhashchange
,例如,设置window.onhashchange=function(e){console.dir(e);}
judgeja链接到这个可能的解决方案(),这似乎让我更接近了。每次我点击一个相关的视频,我都会得到一个警告,内容脚本已经运行,但它仍然是从旧的、原始的DOM中提取的。有趣的是,页面的JavaScript可能会在更新DOM之前更新历史状态。那么你处于比赛状态。尝试将重新注入延迟一段时间。目前,我的.onHistoryStateUpdated()
方法在注入内容脚本时是这样的:我无论如何都不是Javascript开发人员,在谷歌搜索之后,我不确定延迟注入的最佳方法是什么。这样做的最佳实践是什么?