You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js(Pages路由JS)中React Quill编辑器的HTML解析与清理问题

解决方案:React Quill 粘贴内容强制转为纯文本并后端校验

问题分析

你遇到的核心问题是:React Quill 默认会保留粘贴内容的富文本格式,DOMPurify 的作用是清理危险 HTML 而非移除所有标签,Quill 内置的格式清理无法完全处理 Word/网页粘贴的复杂嵌套标签。要实现纯文本公告,需要从「前端拦截粘贴+后端二次校验」两个层面入手。


前端:自定义 Quill 粘贴拦截,强制插入纯文本

通过修改 Quill 的 clipboard 模块,拦截粘贴事件,直接提取粘贴内容的纯文本部分插入编辑器,从源头避免 HTML 标签生成。

import ReactQuill from 'react-quill';
import 'react-quill/dist/quill.snow.css';

const modules = {
  clipboard: {
    // 自定义粘贴处理函数
    matchers: [
      [Node.ELEMENT_NODE, (node, delta) => {
        // 提取节点的纯文本内容
        const text = node.textContent || '';
        // 返回仅包含纯文本的delta对象
        return {
          ops: [{ insert: text }]
        };
      }]
    ]
  },
  // 保留其他需要的模块(如toolbar)
  toolbar: [
    [{ 'header': [1, 2, 3, false] }],
    ['bold', 'italic', 'underline'],
    [{ 'list': 'ordered'}, { 'list': 'bullet' }],
    ['link', 'image'],
    ['clean']
  ]
};

// 在组件中使用配置后的ReactQuill
function AnnouncementForm() {
  const [content, setContent] = useState('');

  return (
    <ReactQuill
      theme="snow"
      value={content}
      onChange={setContent}
      modules={modules}
    />
  );
}

补充:编辑器内容提交前再做一次纯文本转换

如果仍有漏网的标签,在提交表单时手动提取纯文本:

// 提交前处理内容
const handleSubmit = (e) => {
  e.preventDefault();
  // 创建临时DOM元素提取纯文本
  const tempDiv = document.createElement('div');
  tempDiv.innerHTML = content;
  const plainText = tempDiv.textContent || tempDiv.innerText || '';
  
  // 将plainText提交到后端
  fetch('/api/announcements', {
    method: 'POST',
    body: JSON.stringify({ content: plainText }),
    headers: { 'Content-Type': 'application/json' }
  });
};

后端:存入MongoDB前强制清理为纯文本

前端处理可能被绕过(如直接调用API),必须在后端做二次校验,确保存入数据库的是纯文本。

方法1:使用strip-html库(推荐)

npm install strip-html
// 后端API路由(pages/api/announcements.js)
import stripHtml from 'strip-html';
import { MongoClient } from 'mongodb';

export default async function handler(req, res) {
  if (req.method === 'POST') {
    const { content } = req.body;
    // 强制转为纯文本
    const plainTextContent = stripHtml(content).result;

    // 连接MongoDB并存储
    const client = await MongoClient.connect(process.env.MONGODB_URI);
    const db = client.db();
    await db.collection('announcements').insertOne({
      content: plainTextContent,
      createdAt: new Date()
    });
    client.close();

    res.status(200).json({ message: '公告发布成功' });
  }
}

方法2:原生DOMParser提取纯文本(无需额外依赖)

// 后端处理逻辑
const parsePlainText = (html) => {
  const dom = new DOMParser().parseFromString(html, 'text/html');
  return dom.body.textContent || '';
};

// 使用时
const plainTextContent = parsePlainText(content);

验证效果

完成上述配置后:

  1. 从网页/Word粘贴内容时,编辑器会自动转为纯文本
  2. 即使前端有遗漏,后端会强制清理所有HTML标签
  3. 最终存入MongoDB的内容仅包含纯文本,无任何HTML标签

内容的提问来源于stack exchange,提问作者loopstruct

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 21:43:17