尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Ruffle 浏览器扩展 ruffle-extension 深度指南:自动替换网页 Flash 内容、版本协商与 SWF 劫持机制
Ruffle 浏览器扩展 ruffle-extension 深度指南自动替换网页 Flash 内容、版本协商与 SWF 劫持机制【免费下载链接】ruffleA Flash Player emulator written in Rust项目地址: https://gitcode.com/GitHub_Trending/ru/ruffleRuffle 浏览器扩展web/packages/extension让 Ruffle 无需任何网站配合即可在 Chrome、Firefox 和 Safari 中自动接管页面上的 Flash 内容。本文基于仓库中的扩展文档、manifest 与核心 TypeScript 源码完整覆盖扩展的安装方式含各浏览器手动加载步骤、背后的内容脚本注入架构、与网站自带 Ruffle 实例的版本协商机制、可选的 SWF 主框架劫持SWF Takeover功能以及扩展的全部设置项与本地构建流程读完后你可以独立完成扩展的部署、排障与二次构建。一、扩展是什么解决了什么问题官方文档 README.md 对扩展的定位非常直接ruffle-extension is all of the power of Ruffle, in your browser——它把 Ruffle 的全部能力带到浏览器里且不需要网站做任何事扩展会自动把网站上的 Flash 内容替换为 Ruffle 播放器。这与网站嵌入 Ruffle的方案有本质区别网站嵌入需要站点自行加载 Ruffle 脚本并处理object/embed标签而扩展方案在浏览器层面拦截 Flash 内容对站点零依赖。文档同时指出扩展会与已经自行安装了 Ruffle 的网站自动协商确保两个版本不冲突——版本号更新的一方无论来自网站还是扩展始终优先并禁用另一方。从 manifest.json5 可以看出这是一个 Manifest V3 扩展名称为 Ruffle - Flash Emulator主要能力包括content_scripts在all_urls上注入dist/content.jsall_frames: true且run_at: document_start即在所有页面含 iframe的最早时机介入host_permissions: [all_urls]注释说明用途是允许脚本注入 内部播放器绕过 CORS SWF takeoverpermissionsstorage、scripting、declarativeNetRequestWithHostAccess分别对应设置持久化、MAIN 世界脚本注册和 SWF 劫持所需的网络重定向规则action弹出popup.htmloptions_ui指向options.html另有player.html用于内嵌播放器与 SWF 直开。扩展还支持 38 种语言的界面本地化见 assets/_locales 目录每个语言一份messages.json。二、支持的平台与安装方式文档明确扩展运行于Chrome、Firefox 和 Safari 14。除了从 Chrome Web Store / Firefox Add-ons 商店直接安装外还可以下载发布包或自行构建后手动安装各浏览器的步骤如下完整继承自原文档。2.1 Chrome含 Edge、Opera、Brave 等 Chromium 内核浏览器安装*-extension.zip压缩包打开chrome://extensions/在右上角开启开发者模式Developer mode将*-extension.zip文件拖入页面即可。开发期间的快速方式——以加载已解压的扩展方式安装省去重复打包打开chrome://extensions/开启开发者模式点击Load unpacked加载已解压的扩展程序选择assets/文件夹构建产物位于web/packages/extension/assets/下manifest 由 webpack 生成到该目录每次修改后点击扩展卡片上的刷新图标重新加载。2.2 FirefoxDeveloper Edition 或 Nightly注意手动安装未签名扩展仅适用于 Developer Edition / Nightly打开about:addons点击齿轮图标选择 Install Add-on From File...选择.xpi文件由构建流程产出的firefox_unsigned.xpi。2.3 Safari解压*-extension.zip文件运行xcrun safari-web-extension-converter path/to/unzipped_folder/点击 Run on Xcode开启Safari Preferences Advanced Show Develop menu in menu bar开启Develop Allow Unsigned Extensions在Safari Preferences Extensions中勾选启用该扩展。仓库中还包含一个独立的 Safari 辅助工程 safari/含package/Contents/Info.plist与 Swift 入口 safari/src/main.rs配合上述safari-web-extension-converter流程使用。三、内容替换如何实现三层脚本架构扩展能把网站上所有 Flash变成 Ruffle 播放器靠的是分层协作的脚本体系。从 webpack.config.js 的 entry 列表可以看到全部产物content、ruffle、background、player、pluginPolyfill、pluginPolyfillIgnoreOptout、siteContentScript4399等下面按执行角色拆解。3.1 content.ts隔离世界的消息代理content.ts 以隔离世界ISOLATED world注入职责是充当页面世界MAIN world与扩展之间的代理页面加载决策启动时检查是否为 XML 文档isXMLDocument()、全局开关ruffleEnable是否打开、页面是否声明了退出标记。退出标记的判断逻辑在checkPageOptout()中——只要当前页面或顶层文档跨 iframe 向上查找的html元素带有data-ruffle-optout属性即视为网站主动要求禁用 Ruffle消息桥接通过window.postMessage在隔离世界与 MAIN 世界之间转发 JSON 消息请求/响应按index 随机ID配对旧版 Firefox 的降级路径当浏览器不支持 MAIN 世界注入时navigator.wrappedJSObject存在且页面尚未被 Ruffle 接管判断依据是navigator.plugins.namedItem(Shockwave Flash)?.filename ! ruffle.js会用injectScriptRaw把插件 polyfill 源码直接注入页面再以 URL 方式注入dist/ruffle.js。源码注释明确提到polyfill 必须在任何 Flash 检测脚本之前运行但对部分网站可能仍太晚对应 issue #969。3.2 ruffle.tsMAIN 世界中的真正安装者ruffle.ts 运行在 MAIN world文件头部注释解释了原因Chrome 明确禁止扩展在隔离世界注册自定义元素Firefox 虽然允许注册但自定义元素无法暴露有用的 API 表面。它处理来自 content 脚本的load消息设置 webpack 的__webpack_public_path__为扩展的/dist/完整 URL使 WASM 与 Worker 资源能从chrome-extension://或moz-extension://协议加载合并页面自身可能已定义的window.RufflePlayer.config页面配置优先并注入扩展提供的openInNewTab回调调用Setup.installRuffle(extension)来自ruffle-core包完成object/embed/param标签的接管。3.3 background.tsService Worker 总控background.ts 作为 MV3 Service Worker在启动时根据存储中的选项决定是否注册 MAIN 世界脚本。enable()的核心动作是调用chrome.scripting.registerContentScripts动态注册三条内容脚本注意这里复用了 manifest 中content_scripts[0].exclude_matches作为排除列表脚本 ID文件注入世界作用ruffledist/ruffle.jsMAIN在页面中安装 Ruffleplugin-polyfilldist/pluginPolyfill.js或 IgnoreOptout 变体MAIN伪造navigator.plugins中的 Shockwave Flash 条目让站点误以为装了 Flash4399dist/siteContentScript4399.jsMAIN仅针对 4399 网站特定路径的站点定制脚本同时background.ts监听storage.sync的变化ruffleEnable总开关、ignoreOptout、swfTakeover任一改动都会即时触发enable()/disable()实现改设置立即生效。此外它通过chrome.runtime.onMessage处理open_url_in_player消息在player.html#url新标签页中打开 SWF在安装且用户未授予all_urls权限时对应 manifest.json5 第 71 行host_permissions的按需授权场景打开 onboard 引导页。exclude_matches列表值得关注manifest 中维护了一份较长且带注释的域名黑名单如 sso.godaddy.com、twitch 系域名、tiktok、DHL、Costco 各区域域名等这些站点存在注入冲突问题扩展在这些站点上完全静默。四、版本协商扩展与网站自带 Ruffle 如何共存这是该扩展区别于其他 Flash 替代方案的关键机制。文档的描述是扩展会与已安装 Ruffle 的网站协商保证两个版本不冲突较新的 Ruffle无论来自网站还是扩展总是优先并禁用另一方。从仓库中的代码结构可以印证协商的两个基础MAIN 世界是共享的扩展的ruffle.ts与网站自己嵌入的 Ruffle 脚本运行在同一个页面 JS 环境中可以互相观察到window.RufflePlayer、navigator.plugins等全局状态。ruffle.ts在合并配置时特意保留页面上已有的window.RufflePlayer.config即为与网站实例共存留下的接口插件 polyfill 提供可识别的Flash 指纹content 脚本判断页面是否已被 Ruffle 接管依据是navigator.plugins.namedItem(Shockwave Flash)?.filename ruffle.js见 content.ts 第 155-162 行polyfill 正是制造这一指纹的组件其源码位于 plugin-polyfill.ts 与 plugin-polyfill-ignore-optout.ts——后者供忽略退出标记选项使用两者在构建时由 tools/inject_plugin_polyfill.ts 通过搜索替换注入到 content 脚本中。此外网站侧还有主动退出机制只要站点在html上加data-ruffle-optout属性扩展即停止接管除非用户在设置中开启了忽略退出标记对应选项ignoreOptout。五、SWF Takeover把整个主框架变成 Ruffle 播放器除了替换页面内嵌的 Flash 对象扩展还支持一个更激进的可选功能SWF Takeover对应设置项swfTakeover当用户直接导航到一个 SWF 文件主文档即为 Flash时把整个主框架重定向到扩展内置的player.html播放器。实现位于 background.ts 的enableSWFTakeover()第 84-173 行它基于declarativeNetRequest动态注册三条重定向规则全部以content-type响应头条件命中 Flash 响应规则 ID命中条件处理1主框架响应头content-type为application/x-shockwave-flash、application/futuresplash、application/x-shockwave-flash2-preview、application/vnd.adobe.flash.movie重定向到player.html#原URL2URL 以.swf/.spl结尾正则^.*:\/\/.*\/.*\.s(?:wf|pl)(\?.*#\|)$且content-type为application/octet-stream、application/binary-stream或空同上重定向3URL 以.swf/.spl结尾且响应没有content-type头同上重定向重定向使用regexSubstitution: playerPage #\\0即用规则匹配到的原始 URL 作为 hash 参数传给播放器页面。由于responseHeaders条件并非所有浏览器都启用background.ts内置了一个精巧的支持性探测函数isHeaderConditionSupported()第 32-82 行它依次尝试添加一条带responseHeaders的动态规则、再尝试添加一条空的responseHeaders条件——如果第二条不抛错反而说明浏览器跳过了校验功能被 flag 关闭据此区分不支持与支持但未启用。探测不通过时扩展会把responseHeadersUnsupported写入storage.sync设置页面options.ts 第 9-13 行据此隐藏 SWF Takeover 复选框避免给用户展示无效选项。manifest 中还声明了一份静态 DNR 规则资源4399_rules4399_rules.json构建时拷贝到dist/用于 4399 站点的请求改写与siteContentScript4399.js配套。六、设置项与行为参数设置页options.html的选项绑定逻辑在 options.ts 与 common.ts页面中每个.option元素内的input/select按id驼峰化后映射到Options对象common.ts第 4-10 行变更即写入storage.sync同时监听onChanged让弹窗、设置页、内容脚本三处实时同步。扩展专有的布尔选项叠加在ruffle-core的Config.BaseLoadOptions播放器基础配置之上为选项 key类型作用ruffleEnableboolean总开关关闭时后台注销全部动态内容脚本并移除 SWF Takeover 规则background.ts的storage.onChanged监听第 307-330 行ignoreOptoutboolean忽略网站的data-ruffle-optout标记并切换到pluginPolyfillIgnoreOptout.jspolyfill 变体autostartboolean自动开始播放content.ts第 191-200 行将其翻译为播放器配置autoplay: on/auto、静音遮罩显隐、启动画面开关showReloadButtonboolean页面是否显示重载按钮授予部分站点权限时为 true见background.ts的onAddedswfTakeoverboolean上文第五节的 SWF 主框架劫持开关NumberOption/SelectOption类common.ts第 37-112 行还负责把数值输入钳制在min/max范围内、把下拉框选项按settings_id消息键本地化。设置页显示当前构建版本号buildInfo.versionName并提供重置设置按钮resetOptions()会清空storage.sync但保留responseHeadersUnsupported这一与浏览器能力相关的状态。七、本地构建与发布流程扩展的构建入口在 package.jsonnpm 包名ruffle-extension依赖ruffle-core常用脚本# 在 web/packages/extension 目录下 npm run build # 依次执行tsc 类型检查 - build:generic - build:firefox npm run build:generic # webpack --env generic产出 dist/ 注入 polyfill打包为 dist/ruffle_extension.zip npm run build:firefox # webpack --env firefox产出 firefox_unsigned.xpi再尝试签名 npm run checkTypes # tsc --noemit含 tools 子项目构建管线有几个值得了解的细节见 webpack.config.jsmanifest 动态生成源文件是带注释的 manifest.json5version: null由 webpack 填充CopyPlugin将其转换为标准 JSON 输出到assets/manifest.json浏览器差异--env firefox时注入browser_specific_settings.gecko.id默认ruffleruffle.rs可由FIREFOX_EXTENSION_ID环境变量覆盖及data_collection_permissions: { required: [none] }并把background改为 Firefox 支持的scripts数组形式Chromium 侧则使用service_worker并设置incognito: split注释说明Chrome 默认单进程共享扩展会导致无痕标签无法加载扩展页面版本封印version seal设置ENABLE_VERSION_SEALtrue后webpack 要求读取version_seal.json中的version_number/version_channel/version4/firefox_extension_id并抛错提示需用web/packages/core/tools/set_version.js生成——这保证了商店要求的A.B.C.D单调递增版本号在可复现构建中确定不变非封印构建则按CFG_RELEASE_CHANNEL生成version_name如nightly 0.6.0签名Firefox 包通过node tools/submit_xpi.ts上传到 AMO 签名服务依赖reproducible-source.zip与jsonwebtoken/axios见 tools/submit_xpi.ts打包工具为 tools/zip.ts。构建产物的目录约定也解释了 ChromeLoad unpacked为何选择assets/文件夹manifest、dist/脚本与 WASM、images/、_locales/、HTML 页面最终都汇聚在 assets/ 下。八、小结扩展通过document_start的内容脚本 MAIN 世界注入在不改动网站的前提下完成 Flash 标签接管data-ruffle-optout与ignoreOptout构成站点/用户两侧的退出机制与网站自带 Ruffle 的共存依靠 MAIN 世界共享状态协商新版本优先是文档承诺的行为约定SWF Takeover 基于declarativeNetRequest的responseHeaders条件做主框架重定向并用探测函数优雅降级不支持该特性的浏览器安装入口Chrome/Chromium 系拖入 zip 或加载assets/目录解压包、Firefox Developer Edition/Nightly 从.xpi安装、Safari 走xcrun safari-web-extension-converter流程构建侧关注npm run build、ENABLE_VERSION_SEAL、CFG_RELEASE_CHANNEL与 manifest 的 Chromium/Firefox 双形态输出即可复现商店同款扩展包。进一步深入可阅读 web/packages/extension/src 下各入口脚本popup.ts、player.ts、onboard.ts与 web/packages/extension/assets 中的页面资源扩展整体的构建说明并入 web 包 README。【免费下载链接】ruffleA Flash Player emulator written in Rust项目地址: https://gitcode.com/GitHub_Trending/ru/ruffle创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

Redis分布式锁从SETNX到Redisson看门狗:原理、坑与实战

Redis分布式锁从SETNX到Redisson看门狗:原理、坑与实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/9/13 7:24:32
环境变量与 PATH 完全指南:从命令查找到 API 密钥安全的实战手册

环境变量与 PATH 完全指南:从命令查找到 API 密钥安全的实战手册

环境变量与 PATH 完全指南:从命令查找到 API 密钥安全的实战手册 【免费下载链接】easy-vibe 💻 vibe coding 101|The first course for AI-native product builders. 项目地址: https://gitcode.com/GitHub_Trending/ea/easy-vibe 导读…

📅 2026/9/13 7:19:32
MAA 更换主题任务全解析:从任务配置到源码级实现原理

MAA 更换主题任务全解析:从任务配置到源码级实现原理

MAA 更换主题任务全解析:从任务配置到源码级实现原理 【免费下载链接】MaaAssistantArknights 《明日方舟》小助手,全日常一键长草!| A one-click tool for the daily tasks of Arknights, supporting all clients. 项目地址: https://gitc…

📅 2026/9/13 7:19:32
MORE NEWS

更多资讯

📰

像老乡鸡那样做香辣鸡杂:炖菜标准化配方、鸡杂料与分步炖煮流程全解析

像老乡鸡那样做香辣鸡杂:炖菜标准化配方、鸡杂料与分步炖煮流程全解析 【免费下载链接】CookLikeHOC 🥢像老乡鸡🐔那样做饭。已添加2026年发布的《老乡鸡菜品溯源报告 2.0中新出现的菜品。主要部分于2024年完工,非老乡鸡官方仓库。…

📰

Transformer与MoE架构:大模型演进与核心技术解析

1. 大模型架构演进背景2017年Transformer架构的横空出世,彻底改变了自然语言处理领域的游戏规则。这个基于自注意力机制的模型架构,在机器翻译任务上首次实现了完全基于注意力机制的端到端训练,其并行计算特性使得模型训练效率大幅提升。但当…

📰

Zulip Delighted 集成指南:将客户满意度调查反馈实时同步到团队聊天

Zulip Delighted 集成指南:将客户满意度调查反馈实时同步到团队聊天 【免费下载链接】zulip Zulip server and web application. Open-source team chat that helps teams stay productive and focused. 项目地址: https://gitcode.com/GitHub_Trending/zu/zulip …

📰

GoFr vs Fiber:性能导向的 fasthttp 框架与生产级全栈框架的选型对比

GoFr vs Fiber:性能导向的 fasthttp 框架与生产级全栈框架的选型对比 【免费下载链接】gofr An opinionated GoLang framework for accelerated microservice development. Built in support for databases and observability. 项目地址: https://gitcode.com/Git…

📰

MaaAssistantArknights Issue Bot 使用指南:自动标签、手动触发命令与 issue-checker 配置解析

MaaAssistantArknights Issue Bot 使用指南:自动标签、手动触发命令与 issue-checker 配置解析 【免费下载链接】MaaAssistantArknights 《明日方舟》小助手,全日常一键长草!| A one-click tool for the daily tasks of Arknights, supportin…

📰

Wasp 社交内容技能深度解析:用六步逆向工程框架提取爆款内容模式

Wasp 社交内容技能深度解析:用六步逆向工程框架提取爆款内容模式 【免费下载链接】wasp The batteries-included full-stack framework for the AI era. Develop JS/TS web apps (React, Node.js, and Prisma) using declarative code that abstracts away complex …

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬