# 富文本过滤
:::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 层调用此函数处理内容。