
前端文档【免费下载链接】markdown-viewerMarkdown Viewer / Browser Extension项目地址https://gitcode.com/gh_mirrors/ma/markdown-viewer点击查看免费下载Markdown Viewer 是一款为 Chrome 与 Firefox 双端设计的 Markdown 渲染浏览器扩展。由于 Gecko 引擎在 MIME 类型处理、后台页面生命周期和 Content Security Policy 执行上与 Chromium 存在差异Firefox 用户需要针对本地file:///文件、localhost自动重载autoreload以及远程站点做额外的配置。本文基于仓库内的 firefox.md 文档展开并结合 manifest.firefox.json 与背景脚本源码完整覆盖 Firefox 端的兼容边界、Linux 本地文件访问的三种解决方案、autoreload 的可用范围以及被严格 CSP 拦截的远程 origin 限制。兼容性矩阵先看清 Firefox 端能做什么在深入具体配置之前先看 firefox.md 给出的兼容性矩阵它界定了 Firefox 下各类 origin 的渲染Render与自动重载Autoreload能力边界| Origin | 类型 | 所需响应头条件 | Render | Autoreload | | :- | :-: | :- | :- | :- | |file:///| local | 在 Linux 上需要修复 mime type | ✔ | ✖ | |http(s)://| local | 需要content-type: text/plain| ✔ | ✔ | |http(s)://| remote | 需要content-type: text/plain且非严格 CSP | ✔ | ✖ | |http(s)://| remote | 严格 CSPContent Security Policy | ✖ | ✖ |可以得出三个关键结论本地file:///文件可以被渲染但在 Linux 上必须先修复 MIME 类型见下文三种方法且 autoreload 在该矩阵中被标记为不可用localhost 上的http(s)://服务是 Firefox 端体验最完整的场景只要响应头是text/plain既能渲染也能自动重载远程 origin 只要响应头正确且不强制严格 CSP 就能渲染但 autoreload 不生效它只服务于 localhost而一旦远程站点响应头带有严格 CSP扩展将完全无法渲染。另外manifest.firefox.json 中声明了 Firefox 端的最低版本约束browser_specific_settings: { gecko: { id: markdown-vieweroutofindex.com, strict_min_version: 110.0 } }即 Firefox 端要求110.0 及以上版本扩展在 Firefox 的固定 ID 为markdown-vieweroutofindex.com。这与 Chrome 端使用的 manifest.chrome.json 是两套独立 manifestChrome 端以service_worker作为后台而 Firefox 端在 manifest.firefox.json 中以background.scripts列表形式加载一整套后台脚本storage.js、webrequest.js、detect.js等最终入口都是 background/index.js。Linux 下访问本地 file:/// URL 的三种方法问题根源在于与 Chromium 系浏览器不同Firefox 遇到以text/markdowncontent type 分发的文件时会提示下载或调用外部应用打开而不会交给扩展渲染。因此 Markdown 文件必须改以text/plaincontent type 提供。下面是 firefox.md 给出的三种在 Linux 上启用本地file:///访问的方法。方法 1创建~/.mime.types创建~/.mime.types文件写入以下内容typetext/plain extsmd,mkd,mkdn,mdwn,mdown,markdown, descMarkdown document然后重启 Firefox。方法 2Firefox 以 snap 安装时如果 Firefox 是通过 snap 安装的方法 1 不会生效需要创建/home/me/snap/firefox/common/mime.types将me替换为你的用户名内容与方法 1 相同typetext/plain extsmd,mkd,mkdn,mdwn,mdown,markdown, descMarkdown document接着进入 Firefox 的about:config搜索helpers.private_mime_types_file把其中的默认路径替换为/home/me/snap/firefox/common/mime.types同样把me换成你的用户名最后重启 Firefox。方法 3使用 freedesktop.org 的 shared-mime-info 机制创建~/.local/share/mime/packages/text-markdown.xml写入以下内容?xml version1.0? mime-info xmlnshttp://www.freedesktop.org/standards/shared-mime-info mime-type typetext/plain glob pattern*.md/ glob pattern*.mkd/ glob pattern*.mkdn/ glob pattern*.mdwn/ glob pattern*.mdown/ glob pattern*.markdown/ /mime-type /mime-info然后执行update-mime-database ~/.local/share/mime渲染检测如何依赖 content type配置完成后扩展在 background/detect.js 中执行内容检测。从源码结构看检测逻辑对响应头使用如下正则/\btext\/(?:(?:(?:x-)?markdown)|plain)\b/i.test(content)也就是说text/markdown、text/x-markdown、text/plain三种 content type 都在识别范围内见 background/detect.js。同时options/origins.js 中的 Advanced Options 页面上每个 origin 的 Content Type Detection 开关明确列出了这三种类型。这也解释了为什么 Linux 下必须让.md文件解析为text/plain——它是 Firefox 端打通本地文件渲染的必要条件。另外值得注意的是 Firefox 与 Chrome 在文件访问权限上的差异。Chrome 端需要用户手动在chrome://extensions打开 Allow access to file URLs 开关见 README.md 的After Install一节而 Firefox 没有这个开关。options/origins.js 中的处理逻辑印证了这一点chrome.extension.isAllowedFileSchemeAccess((isAllowedAccess) { state.file /Firefox/.test(navigator.userAgent) ? true // ff: Allow access to file URLs option isnt available : isAllowedAccess m.redraw() })因为在 manifest.firefox.json 中host_permissions已直接声明了file:///*Firefox 端的 File Access 状态被固定为可用trueAdvanced Options 页也不会出现 Allow Access 按钮。localhost 上的 Autoreload原理、示例服务与配置autoreload功能在 Firefox 端只对localhost分发的内容可用由于 CSPContent Security Policy限制它在file:///URL 上无法工作与上文兼容性矩阵中file:///的 Autoreload 列一致。任何文件服务器都可以用作本地服务前提是把 markdown 文件以text/plaincontent type 分发。firefox.md 给出了一个基于 Node.js 的示例文件服务器将me替换为你的用户名var express require(express) var serveIndex require(serve-index) var serveStatic require(serve-static) express() // serve markdown files with content-type: text/plain in Firefox .use((req, res, next) { // by default serve-static serves markdown content with content-type: text/markdown if ( /Firefox/.test(req.headers[user-agent]) // the default Path Matching RegExp in Markdown Viewer /\.(?:markdown|mdown|mkdn|md|mkd|mdwn|mdtxt|mdtext|text)(?:#.*|\?.*)?$/.test(req.url) ) { res.setHeader(content-type, text/plain; charsetutf-8) } next() }) .use(serveStatic(/home/me)) .use(/, serveIndex(/home/me, {icons: true, view: details})) .listen(8000)这段中间件做了两件事识别 Firefox 的 User-Agent并且当请求路径命中扩展的默认路径匹配正则时把content-type改写成text/plain; charsetutf-8——因为serve-static默认会以text/markdown分发 markdown 文件而那正是 Firefox 会触发下载行为的问题类型。这个正则与扩展内部默认值完全一致可以在 background/storage.js 的默认配置中看到var match \\.(?:markdown|mdown|mkdn|md|mkd|mdwn|mdtxt|mdtext|text)(?:#.*|\\?.*)?$它匹配以 markdown 扩展名结尾markdown、mdown、mkdn、md、mkd、mdwn、mdtxt、mdtext、text且可选跟随 hash 或 querystring 的 URL。配置 origin 并运行打开扩展的 Advanced Options 页添加http://localhost这个 origin注意不带端口。用 Node.js 运行上面的 JavaScript 文件在 Firefox 中访问http://localhost:8000。之所以不带端口是因为 Firefox 端添加 origin 时会主动剥掉端口号。options/origins.js 中有对应处理if (/Firefox/.test(navigator.userAgent) /:\d{2,4}/.test(origin)) { origin origin.replace(/(:\d{2,4})/, ) }因此你只添加http://localhost即可覆盖任意端口。README.md 中Enable Site Access一节也说明了同样的规则添加http://localhost可启用 localhost 上的所有端口添加http://localhost:3000则只启用特定端口。除了localhost还可以使用hosts文件中解析到 localhost 的任意主机名例如127.0.0.1 ssd此时只需在 Advanced Options 页添加对应的 originhttp://ssd即可。上述服务脚本还可以通过 SystemD 或任意其他服务管理器配置为开机自启。autoreload 的源码级实现结合源码可以看清 autoreload 的完整调用链它在state.content.autoreload为true时才会被注入内容脚本轮询background/inject.js 按选项决定是否注入 content/autoreload.js。该脚本以 content/index.js 中定义的state.reload.ms1000 毫秒为周期轮询对http(s)://页面直接发起带?preventCacheDate.now()防缓存参数的 XHR GET 请求每次收到响应后与上次内容比对若 markdown 文本发生变化就置state.reload.md true并重新渲染。file:///的降级路径content/autoreload.js 中当location.protocol file:时内容脚本不直接发 XHR而是通过chrome.runtime.sendMessage({message: autoreload, location})委托给后台页面后台在 background/messages.js 中收到该消息后调用 background/xhr.js 的fetch同样追加?preventCacheDate.now()读取文件内容再回传。不过按 firefox.md 的兼容性矩阵Firefox 端file:///的 autoreload 整体标记为不可用该分支的实际生效范围以矩阵为准。非 localhost 保护background/webrequest.js 中注册了webRequest.onCompleted监听webRequest是按需申请的可选权限一旦某次请求解析出的 IP不是127.0.0.1也不是::1就会向该标签页发送{message: autoreload}消息content/index.js 收到后执行clearInterval(state.reload.interval)停止轮询。从源码结构看这正是autoreload 只对解析到本地回环地址的 host 生效这一约束的落地实现。权限回收background/webrequest.js 在 autoreload 开启时动态申请webRequest权限并挂上监听器关闭时则移除监听器与权限保证不使用时不占额外权限。严格 CSP 的远程 origin无法绕过的限制第三类场景是远程 origin。规则是以text/plain分发 markdown、且不强制严格 CSP的远程 origin可以在 Advanced Options 页添加后正常渲染。文档以gitlab.com和bitbucket.org上托管的 raw 文件如 markdown-syntax 项目的README.mdraw 地址为例说明这类内容可以启用并被渲染响应头带有严格 CSP 的远程 origin例如content-security-policy: default-src none; style-src unsafe-inline; sandbox会被 Firefox 直接拦截。文档以 GitHub 的raw.githubusercontent.com为例即使已在 Advanced Options 页启用了该 origin内容依然无法渲染。这一限制来自浏览器安全模型而非扩展本身远程页面的严格 CSP 禁止了扩展注入脚本/样式所需的来源Firefox 对此执行得比 Chromium 更严格。CHANGELOG.md 也记录了 v5.0 中disabling CSP is no longer possible不再允许关闭 CSP的决定即扩展侧从 v5.0 起就放弃了绕过 CSP 的选项与这一行为一致。Firefox 端的其余适配细节除上述三大主题外源码中还有几处与 Firefox 行为直接相关的适配值得了解后台检测流程差异background/detect.js 中的ff分支先判断chrome.runtime.getBrowserInfo是否存在、且 manifest 是否声明了browser_specific_settings.gecko。在 Firefox 下若标签页已有内容脚本响应通过向该标签页发送ping消息试探成功则直接跳过重复注入noop否则才通过chrome.scripting.executeScript读取document.contentType与 URL 执行内容检测命中后再执行 background/inject.js 的完整注入流程。可以推断这是为了适配 Firefox 与 Chrome 在页面加载生命周期时序上的差异。Advanced Options 的打开方式background/messages.js 处理popup.advanced消息时Firefox 下通过chrome.management.getSelf取到extension.optionsUrl再新建标签页打开其他浏览器则直接调用chrome.runtime.openOptionsPage()。文件服务器响应头与检测逻辑的闭环远程 origin 的渲染判定要求 header detection 与 path matching同时命中两者都开启时对应 background/detect.js 中origin.header origin.path origin.match的组合条件。这解释了为什么文档中反复强调远程与本地 HTTP 场景都requirescontent-type: text/plain。小结Firefox 端的能力边界由兼容性矩阵界定本地file:///可渲染Linux 需修复 MIME、localhost HTTP 可渲染 autoreload、非严格 CSP 的远程 origin 仅可渲染、严格 CSP 远程 origin 完全不可用Linux 本地文件访问的三条路径分别是~/.mime.types、snap 环境下的snap/firefox/common/mime.typeshelpers.private_mime_types_file指向、以及~/.local/share/mime/packages/update-mime-database核心目标都是让.md等扩展名解析为text/plainautoreload 依赖text/plain的本地文件服务文档提供了完整 Express 示例、Advanced Options 中添加不带端口的http://localhost或hosts中解析到 localhost 的自定义主机名底层由内容脚本每秒轮询 后台webRequest监听共同实现涉及 Firefox 的最低版本110.0、origin 端口剥离、CSP 不可禁用等行为均可在 manifest.firefox.json、options/origins.js 与 CHANGELOG.md 中查证。主要参考文件firefox.md、README.md、manifest.firefox.json、manifest.chrome.json、background/detect.js、background/webrequest.js、background/xhr.js、background/messages.js、background/storage.js、background/inject.js、content/autoreload.js、content/index.js、options/origins.js、CHANGELOG.md。赞分享前端文档【免费下载链接】markdown-viewerMarkdown Viewer / Browser Extension项目地址https://gitcode.com/gh_mirrors/ma/markdown-viewer点击查看免费下载相关推荐Markdown Viewer扩展在Firefox中自动重载功能失效的解决方案Markdown Viewer扩展在Firefox中自动重载功能失效的解决方案 问题现象分析 当用户在Firefox浏览器中使用Markdown Viewer扩前端文档GitHub MCP Server本地化区域适配方案GitHub MCP Server本地化区域适配方案 概述 GitHub MCP ServerModel Context Protocol Server是后端MCP 服务AI 应用【限时免费】 深入理解x-file-storage本地存储配置与访问机制深入理解x file storage本地存储配置与访问机制 本地存储配置详解 x file storage作为一款优秀的文件存储管理框架提供了灵活的本地存储配后端对象存储存储上一篇终极指南如何使用PyRosetta进行蛋白质结构预测与设计下一篇LyricsX完全指南从新手到专家的桌面歌词同步实战手册创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考