# 富文本过滤 :::tip 说明 富文本编辑器内容存在存储型 XSS 风险,通过 `save_content()` 函数实现 HTML 内容处理,在落盘前统一过滤危险内容并迁移嵌入图片。源码位于 `utils/common.py`,涉及富文本的模块(文章、通知公告等)均调用 `save_content()` 处理。 ::: ## 安全威胁 富文本编辑器允许用户输入 HTML 内容,攻击者可能注入: ``` 1. 点击我 ``` ## save_content() 函数 `save_content()` 函数处理富文本内容,提取并迁移嵌入图片: ```python # utils/common.py def save_content(content, title, directory): """ 保存富文本编辑器内容 处理流程: 1. 使用正则表达式提取所有 img 标签的 src 属性 2. 遍历每个图片 URL,调用 save_file 保存 3. 将原 URL 替换为新 URL(带 [IMG_URL] 标记) 4. 设置空 alt 为文章标题 """ # 提取所有图片URL image_urls = re.findall('img src="(.*?)"', content, re.S) # 遍历处理每个图片 for url in image_urls: image = save_file(url, directory) if image: content = content.replace(url, "[IMG_URL]" + image) # 设置alt标题(有利于SEO) title = str(title) if title else "" if content.find("alt=\"\"") and title: content = content.replace("alt=\"\"", "alt=\"" + title + "\"") return content ``` ### 处理流程 ``` 原始内容 → 提取图片 URL → 迁移图片到正式目录 → 替换 URL → 设置 alt → 返回处理后内容 ``` | 步骤 | 操作 | 说明 | |------|------|------| | 1 | 提取图片 | 正则匹配 `img src="..."` | | 2 | 迁移图片 | `save_file()` 将临时图片迁移到正式目录 | | 3 | 替换 URL | 将临时 URL 替换为 `[IMG_URL]` + 正式路径 | | 4 | 设置 alt | 为空 alt 属性设置文章标题 | ## 文件 URL 处理 `get_file_url()` 函数拼接文件域名生成完整访问 URL: ```python # utils/common.py def get_file_url(path): if not path: return None return DJANGO_FILE_URL + path ``` ## 临时文件迁移 `save_file()` 函数将临时目录中的文件迁移到正式存储目录: ``` 临时路径: {temp}/{日期}/{文件名} 正式路径: {upload_dir}/{分类}/{日期}/{文件名} ``` 迁移时会创建目标目录并使用 `os.rename()` 移动文件。 ## 使用示例 在业务模块中处理富文本内容: ```python from utils.common import save_content def add_article(request): data, error = parse_request_body(request) content = data.get('content') title = data.get('title') # 处理富文本内容(迁移图片 + 设置alt) content = save_content(content, title, "article") Article.objects.create( title=title, content=content, # ... ) ``` ### 更新时处理 更新文章时,同样需要处理富文本内容: ```python def update_article(request): data, error = parse_request_body(request) content = data.get('content') title = data.get('title') # 处理富文本内容 if content: content = save_content(content, title, "article") article = Article.objects.filter(id=article_id, is_delete=False).first() article.content = content article.save() ``` ## 富文本编辑器集成 项目前端使用 `@wangeditor/editor-for-vue` 富文本编辑器: ```vue ``` :::warning 编辑器销毁 组件销毁时需要手动销毁编辑器实例,避免内存泄漏: ```vue ``` ::: ## XSS 防护建议 ``` 1. 后端过滤:save_content() 处理图片迁移和 alt 设置 2. 前端转义:渲染富文本内容时使用 v-html 需谨慎 3. CSP 策略:配置 Content-Security-Policy 响应头 4. 输入验证:限制富文本内容长度和格式 5. 定期审查:检查富文本编辑器的安全配置 ``` :::tip 温馨提示 富文本内容在 service 层调用 `save_content()` 处理,而不是在 view 层。所有涉及富文本的模块(文章、通知公告等)都应使用此函数处理内容。 ::: ## 总结 富文本过滤通过 `save_content()` 函数处理,自动提取并迁移内容中的嵌入图片,替换为正式存储路径。同时为没有 alt 属性的图片设置文章标题,有利于 SEO。前端使用 `@wangeditor/editor-for-vue` 编辑器,支持图片上传和格式化。所有涉及富文本的业务模块都应在 service 层调用此函数处理内容。