# Personal Blog - Markdown 渲染技术方案 > 后端生成 HTML → 访客端直接渲染 > 管理端实时预览 → react-markdown --- ## 1. 整体策略 项目采用 **"后端预渲染 HTML + 前端直接展示"** 的架构: ``` 数据库 (Markdown 文本) │ ▼ 后端 FastAPI ── article_to_html() ──► HTML 字符串 │ │ │ API 响应 │ │ { content_html: "..." } │ │ │ └──────────────┬───────────────┘ │ ▼ 访客端 React dangerouslySetInnerHTML │ ▼ 浏览器渲染最终页面 ``` ### 1.1 为什么选择后端预渲染? 1. **性能**:访客端不需要加载 Markdown 解析库,减少 JS bundle 体积 2. **一致性**:前后端解析规则统一,避免渲染差异 3. **SEO**:服务端返回的 HTML 可被搜索引擎抓取(配合 SSR 或预渲染更优) 4. **安全**:后端可控 HTML 净化,防止 XSS --- ## 2. 后端渲染 (app.py) ### 2.1 核心函数:`article_to_html` ```python def article_to_html(content: str) -> str: """将 Markdown 内容转换为 HTML""" if not content: return "" # 转换 Markdown → HTML html_content = markdown.markdown( content, extensions=[ 'extra', # 表格、属性列表、定义列表等 'codehilite', # 代码语法高亮 'toc', # 目录生成 'fenced_code', # 围栏代码块 ] ) # 包装容器 return f'
{html_content}
' ``` ### 2.2 Markdown 扩展说明 | 扩展 | 功能 | |------|------| | `extra` | 支持表格、缩写、属性列表、定义列表、围栏代码块、脚注等 | | `codehilite` | 代码块语法高亮(需 Pygments) | | `toc` | 自动生成目录(Table of Contents) | | `fenced_code` | GitHub 风格的三反引号代码块 | ### 2.3 支持的 Markdown 语法 | 语法 | 示例 | 输出 | |------|------|------| | 标题 | `# 一级标题` | `

` | | 加粗 | `**文字**` | `` | | 斜体 | `*文字*` | `` | | 链接 | `[文字](url)` | `` | | 图片 | `![描述](url)` | `` | | 引用 | `> 引用内容` | `
` | | 列表 | `- 项目` / `1. 项目` | `
    ` / `
      ` | | 代码行 | `` `代码` `` | `` | | 代码块 | ` ```python ` | `
      ` |
      | 表格 | `| 列1 | 列2 |` | `` |
      | 分隔线 | `---` | `
      ` | ### 2.4 代码高亮 `codehilite` 扩展配合 Pygments 实现代码高亮: ```python # 输入 (Markdown) ```python def hello(): print("Hello World") ``` # 输出 (HTML)
      
          def hello():
              print("Hello World")
        
      ``` **注意**:当前项目 `requirements.txt` 未包含 `pygments`,代码高亮样式可能不生效。如需完整高亮,需额外安装: ```bash pip install pygments ``` ### 2.5 文章 API 的 HTML 字段 文章详情接口返回双字段: ```json { "id": 1, "title": "文章标题", "content": "# Markdown 原文\n\n正文内容...", "content_html": "

      Markdown 原文

      正文内容...

      ", "summary": "摘要", "...": "..." } ``` - `content`:原始 Markdown,用于管理端编辑 - `content_html`:预渲染 HTML,用于访客端展示 --- ## 3. 访客端渲染 (PostDetail.jsx) ### 3.1 渲染方式 访客端直接使用 `dangerouslySetInnerHTML` 注入后端返回的 HTML: ```jsx // PostDetail.jsx
      ``` ### 3.2 样式隔离 通过 CSS 类 `.article-content` 对文章正文进行样式隔离,避免与页面其他样式冲突: ```css /* index.css 中的文章样式 */ .article-content { @apply text-gray-800 leading-relaxed; } .article-content h1 { @apply text-2xl font-bold mt-8 mb-4; } .article-content h2 { @apply text-xl font-bold mt-6 mb-3; } .article-content p { @apply mb-4; } .article-content pre { @apply bg-gray-100 p-4 rounded-lg overflow-x-auto mb-4; } .article-content code { @apply bg-gray-100 px-1 py-0.5 rounded text-sm; } .article-content pre code { @apply bg-transparent p-0; } .article-content blockquote { @apply border-l-4 border-brutal-yellow pl-4 italic my-4; } .article-content img { @apply max-w-full rounded-lg; } .article-content table { @apply w-full border-collapse mb-4; } .article-content th, .article-content td { @apply border border-gray-300 px-3 py-2; } .article-content th { @apply bg-gray-100 font-bold; } ``` ### 3.3 XSS 防护 当前项目依赖 **后端输出可信 HTML** 来防范 XSS: - Markdown 解析在后端完成 - 不渲染用户直接输入的 HTML(Markdown 语法会被转义为纯文本) - 图片 URL 经过下载到本地处理,避免外链图片的潜在风险 **局限性**:当前未使用 `bleach` 等 HTML 净化库对输出进行过滤。如果管理员在 Markdown 中嵌入恶意 HTML(如 `