最小权限设计的微信公众号 Markdown 发布扩展
✅ 最小权限 - 仅需微信公众号域名访问权限 ✅ 无 CSP 问题 - 纯 Content Script 实现,无 Service Worker ✅ 简单易用 - 在微信公众号后台直接使用 ✅ 自动认证 - 读取浏览器登录态,无需手动配置
{
"permissions": ["storage", "activeTab"],
"host_permissions": ["https://mp.weixin.qq.com/*"]
}storage- 存储用户设置和 Markdown 模板activeTab- 访问当前标签页(用户主动触发)https://mp.weixin.qq.com/*- 仅微信公众号后台
对比完整版 Wechatsync:
- 原版需要:
http://*/*+https://*/*(所有网站) - 本扩展: 仅微信域名 (减少 95% 权限范围)
- 打开 Chrome:
chrome://extensions - 启用 "开发者模式"
- 点击 "加载已解压的扩展程序"
- 选择此目录
- 登录微信公众号后台: https://mp.weixin.qq.com/
- 点击浏览器工具栏中的扩展图标
- 在弹出窗口中:
- 粘贴 Markdown 内容
- 或从文件选择
.md文件
- 点击"发布到草稿箱"
- 等待处理完成,获取草稿链接
- Markdown → HTML 转换 (marked.js)
- CSS 样式内联 (juice.js)
- 图片自动上传到微信 CDN
- 发布到微信草稿箱
- 实时进度显示
- LaTeX 数学公式支持
- 代码块语法高亮
- 自定义样式模板
- 草稿管理功能
用户访问 mp.weixin.qq.com
↓
Content Script 自动注入
↓
读取 document.cookie (获取 token)
↓
直接调用微信 API (fetch)
↓
无需 Background Service Worker
优势:
- ✅ 避免 CSP 限制 (无 eval/Function)
- ✅ 直接访问页面上下文
- ✅ 无消息传递开销
- ✅ 实现简单,易维护
wechat-md-extension/
├── manifest.json # 扩展配置(最小权限)
├── icons/ # 扩展图标
│ ├── icon-16.png
│ ├── icon-48.png
│ └── icon-128.png
├── popup/ # 弹出界面
│ ├── popup.html
│ ├── popup.js
│ └── popup.css
├── content/ # Content Script
│ ├── publisher.js # 核心发布逻辑
│ └── ui.css # 注入的 UI 样式
├── lib/ # 第三方库
│ ├── marked.min.js # Markdown 解析器
│ └── juice.browser.min.js # CSS 内联工具
└── README.md
// 使用 marked.js 解析 Markdown
const html = marked.parse(markdown)
// 使用 juice 内联 CSS 样式
const WEIXIN_CSS = `
p { color: rgb(51,51,51); font-size: 15px; line-height: 1.75em; }
h1 { font-size: 1.25em; font-weight: bold; }
...
`
const styledHtml = juice.inlineContent(`<section>${html}</section>`, WEIXIN_CSS)async function uploadImage(imageUrl) {
const blob = await fetch(imageUrl).then(r => r.blob())
const formData = new FormData()
formData.append('file', blob, 'image.jpg')
const response = await fetch(
`https://mp.weixin.qq.com/cgi-bin/filetransfer?action=upload_material&token=${token}`,
{ method: 'POST', body: formData }
)
const { cdn_url } = await response.json()
return cdn_url
}async function publishArticle(title, content) {
const formData = new URLSearchParams({
token,
title0: title,
content0: content,
auto_gen_digest0: '1',
// ... 其他参数
})
const response = await fetch(
'https://mp.weixin.qq.com/cgi-bin/operate_appmsg?sub=create',
{
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: formData
}
)
const { appMsgId } = await response.json()
return `https://mp.weixin.qq.com/cgi-bin/appmsg?appmsgid=${appMsgId}`
}| 方案 | 权限 | CSP 安全 | 实现复杂度 |
|---|---|---|---|
| 本扩展 (Content Script) | ✅ 最小 | ✅ 是 | ✅ 低 |
| Wechatsync (MV2) | ❌ 全域 | ||
| Node.js CLI | ✅ 无 | ✅ 是 |
- 检查 Chrome 版本 (需 v88+)
- 确认已启用开发者模式
- 确认已登录微信公众号后台
- 检查浏览器控制台错误信息
- 验证 token 是否有效
- 检查图片 URL 是否可访问
- 验证图片大小 (微信限制 10MB)
- 访问
chrome://extensions - 找到此扩展,点击"检查视图"
- 在微信后台页面,按 F12 查看 Content Script 日志
修改后需重新加载扩展:
- 在
chrome://extensions点击刷新按钮 - 或者 Ctrl+R 重新加载页面
MIT License
- Wechatsync - 多平台同步扩展
- marked - Markdown 解析器
- juice - CSS 内联工具
欢迎提交 Issue 和 Pull Request!