Tampermonkey脚本遇CSP错误被拦截,Memrise插入iframe场景如何修复
问题原因
- 你当前使用
@grant none配置,脚本会直接注入到页面的原生上下文执行,完全受Memrise站点设置的内容安全策略(CSP)约束 - Memrise的CSP规则禁止加载未在白名单内的第三方站点作为iframe源,同时拦截了上下文内的内嵌脚本执行逻辑
修复方案
修改脚本头部的配置,使用油猴提供的GM API绕过页面CSP限制:
- 把
@grant none替换为@grant GM_addElement,启用油猴的内置元素创建API,该API不受页面CSP约束 - 替换原生的
createElement+appendChild逻辑,使用GM_addElement创建并插入iframe,同时增加元素加载等待逻辑、URL编码处理避免特殊字符报错、重复插入判断
修改后的完整代码如下:
// ==UserScript== // @name Merise // @namespace http://tampermonkey.net/ // @version 0.2 // @description Add dictionary iframe to Memrise // @author k1 // @match https://app.memrise.com/aprender/* // @icon https://www.google.com/s2/favicons?domain=memrise.com // @grant GM_addElement // ==/UserScript== (function() { 'use strict'; // 轮询等待目标元素加载完成,适配单页应用动态渲染逻辑 const checkTimer = setInterval(() => { const wordEle = document.querySelector(".sc-1nck79x-5.jPETsr"); const containerEle = document.querySelector(".sc-r1ec2z-1.evBYsl"); // 元素存在且未插入过iframe时执行 if (wordEle && containerEle && !containerEle.querySelector('#custom-dict-iframe')) { clearInterval(checkTimer); const targetUrl = "https://learnersdictionary.com/definition/" + encodeURIComponent(wordEle.innerText.trim()); GM_addElement(containerEle, 'iframe', { id: 'custom-dict-iframe', height: '500px', src: targetUrl, style: 'max-width: 90%; border: none; margin: 1rem 0;' }); } }, 300); })();
额外注意事项
- 代码中使用的类名是Memrise React框架生成的动态类名,站点版本更新后类名可能会变更,如果后续脚本失效,可自行检查页面元素替换为最新的类名
- 如果修改后仍然加载失败,可以打开油猴脚本的设置页面,将该脚本的「注入模式」修改为「内容脚本」,进一步绕过页面CSP限制
内容的提问来源于stack exchange,提问作者Keivan
相关产品推荐
相关产品推荐

