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

如何在ReactElement中安全处理含#话题标签的文本并添加自定义HTML

安全处理含话题标签的文本渲染问题

我从数据库获取包含#话题标签的文本,需要将其作为<Post>元素的内部内容,希望把话题标签包装在<a>元素中,而不是直接作为纯文本传入<Post>。

目前我的实现方式如下:

function Post(props: Post) {
  // ...
  return(
    <div>
      {textPreprocessor(props.text)}
    </div>
)}

//...

const textPreprocessor = (content : string) : React.ReactNode => {
    // adds hashtags
    let words = content.split(" ");
    let htmlString = ""
    words.forEach(word  => {
        if(word[0] === "#") {
            htmlString += `<a href='hashtag/:${word}'/>${word}</a> `
        }
        else{
            htmlString += `${word} `
        }
    })
    
    return <div dangerouslySetInnerHTML={{__html: htmlString}} />;
}

这个方案虽然能运行,但存在极高安全风险:数据库中的恶意HTML/JS代码会在前端执行。请问有没有更安全的实现方式?


安全实现方案

核心思路是彻底抛弃dangerouslySetInnerHTML,用React原生元素构建内容,利用React自动转义纯文本的特性规避注入风险。

方法1:拆分文本为React节点数组

通过正则拆分文本,将话题标签转为<a>元素,普通文本直接保留,组成React节点数组返回:

function Post(props: Post) {
  return (
    <div>
      {textPreprocessor(props.text)}
    </div>
  );
}

const textPreprocessor = (content: string): React.ReactNode[] => {
  // 正则匹配#开头的话题标签,可根据需求调整规则(比如支持中文标签)
  const hashtagRegex = /(#[\w\u4e00-\u9fa5]+)/g;
  // 拆分文本为「普通内容」和「话题标签」交替的数组
  const contentParts = content.split(hashtagRegex);

  return contentParts.map((part, index) => {
    // 判断当前片段是否为话题标签
    if (part.startsWith('#')) {
      return (
        <a 
          key={index} 
          href={`hashtag/:${part}`}
        >
          {part}
        </a>
      );
    }
    // 普通文本直接返回,React会自动转义<、>、&等特殊字符
    return part;
  });
};
  • 正则可按需调整,比如要支持带中文的标签,就把匹配规则改成/#[\w\u4e00-\u9fa5]+/g
  • 用split拆分后遍历数组,标签转成<a>,普通文本原样返回,完全不会触发恶意代码执行

方法2:用轻量库简化代码(可选)

如果需要同时处理@提及、表情等多种格式,可使用react-string-replace这类库简化逻辑,本质和方法1一致:

import replace from 'react-string-replace';

const textPreprocessor = (content: string): React.ReactNode => {
  return replace(content, /(#[\w\u4e00-\u9fa5]+)/g, (match, index) => (
    <a key={index} href={`hashtag/:${match}`}>
      {match}
    </a>
  ));
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 02:25:29