Chrome扩展开发:declarativeContent API能否访问head中的AMP链接?
解决Chrome扩展检测AMP页面的问题
嘿,刚好我之前研究过Chrome扩展里检测AMP页面的问题,来给你捋一捋!首先明确一点:chrome.declarativeContent API的PageStateMatcher是可以通过CSS选择器匹配head元素的,你遇到的问题大概率是选择器写法或者页面加载时机的问题,先给你讲最直接的解决方案,再说说复杂场景下的替代方案。
一、静态AMP链接的场景(最常用)
如果页面的AMP链接是在初始HTML的head里静态存在的,只要写对CSS选择器就能搞定。比如你要匹配带有<link rel="amphtml">标签的页面,规则应该这么写:
chrome.runtime.onInstalled.addListener(() => { // 先清除旧规则 chrome.declarativeContent.onPageChanged.removeRules(undefined, () => { const ampDetectionRule = { conditions: [ new chrome.declarativeContent.PageStateMatcher({ pageUrl: { schemes: ['http', 'https'] }, // 只在http/https页面生效 css: ["link[rel='amphtml']"] // 匹配head里的AMP链接标签 }) ], actions: [new chrome.declarativeContent.ShowPageAction()] // 激活扩展图标 }; // 添加新规则 chrome.declarativeContent.onPageChanged.addRules([ampDetectionRule]); }); });
为什么之前可能没生效?检查下这几点:
- 你的CSS选择器是不是写错了?比如引号的问题,或者rel属性值拼写错误(是
amphtml不是amp) - 页面的AMP链接是不是在主框架里?如果是嵌套iframe里的,
PageStateMatcher默认只检测主框架,需要额外配置frameIds
二、动态添加AMP链接的场景(复杂情况)
如果页面的AMP链接是通过JS动态插入到head里的,PageStateMatcher就无能为力了——因为它只会在页面初始加载时匹配一次DOM,动态变化的元素不会触发重新匹配。这时候就得换方案:用Content Script + Mutation Observer来检测,再通知后台脚本控制扩展状态。
步骤1:配置Manifest.json
先在manifest里注册Content Script,让它注入到所有页面:
{ "manifest_version": 3, "name": "AMP Detector", "version": "1.0", "content_scripts": [ { "matches": ["<all_urls>"], "js": ["content.js"], "run_at": "document_idle" // 页面加载完成后再注入 } ], "permissions": ["activeTab", "tabs"], "action": { "default_icon": "icon.png" } }
步骤2:编写Content Script(content.js)
这里用Mutation Observer监听head的变化,检测静态或动态添加的AMP链接:
// 先检查初始DOM里有没有AMP链接 const checkAmpLink = () => { return document.querySelector('link[rel="amphtml"]') !== null; }; if (checkAmpLink()) { // 告诉后台脚本当前页面有AMP版本 chrome.runtime.sendMessage({ hasAMP: true }); } else { // 监听head的DOM变化,检测动态添加的AMP链接 const observer = new MutationObserver((mutations) => { mutations.forEach(mutation => { if (mutation.addedNodes.length && checkAmpLink()) { chrome.runtime.sendMessage({ hasAMP: true }); observer.disconnect(); // 检测到后就停止监听 } }); }); observer.observe(document.head, { childList: true }); }
步骤3:编写后台脚本(background.js)
接收Content Script的消息,控制扩展图标的激活状态:
// 页面切换时默认禁用图标,除非Content Script确认有AMP chrome.tabs.onActivated.addListener(activeInfo => { chrome.action.disable(activeInfo.tabId); }); // 监听Content Script的消息 chrome.runtime.onMessage.addListener((message, sender) => { if (message.hasAMP) { chrome.action.enable(sender.tab.id); } else { chrome.action.disable(sender.tab.id); } });
总结
- 静态AMP链接:直接用
declarativeContent的CSS选择器就能搞定,简单高效 - 动态AMP链接:必须用Content Script配合Mutation Observer来实时检测,虽然麻烦但覆盖所有场景
内容的提问来源于stack exchange,提问作者NHagar
相关产品推荐
相关产品推荐

