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

如何在React函数式组件中解析API返回的特殊字符编码?

解决React中API返回特殊字符编码无法解析的问题

你遇到的是API返回HTML实体编码内容(比如"、<、&这类),React默认会转义这些字符,导致直接渲染时显示原编码而非正常文本。下面给两种简便的解决方法:


方法1:用dangerouslySetInnerHTML快速实现

这是最直接的方式,让React直接解析HTML实体内容:

修改你的Question、Category等需要渲染编码内容的组件:

const Question = ({ q }) => {
  // 用__html字段传入编码内容,React会自动解析实体
  return <div dangerouslySetInnerHTML={{ __html: q }} />;
};

const Category = ({ type }) => {
  return <div dangerouslySetInnerHTML={{ __html: type }} />;
};

const Answer = ({ wrong, right, questionType }) => {
  return (
    <div>
      {questionType === "boolean" && <div> TRUE OR FALSE</div>}
      {questionType === "multiple" && (
        <div>
          {wrong.map((ans, idx) => (
            <div key={idx} dangerouslySetInnerHTML={{ __html: ans }} />
          ))}
          <div dangerouslySetInnerHTML={{ __html: right }} />
        </div>
      )}
    </div>
  );
};

注意:这个属性的命名带有「dangerously」是因为如果内容包含恶意HTML标签(比如<script>),会有XSS风险。但OpenTDB这类公开问答API返回的内容通常是安全的,所以可以放心使用。


方法2:自定义解码函数(更安全可控)

如果担心内容安全性,或者只想解析文本不想处理HTML标签,可以写一个通用的解码函数,把HTML实体转成普通字符串:

// 通用解码函数
function decodeHtmlEntities(str) {
  const parser = new DOMParser();
  const doc = parser.parseFromString(`<!doctype html><body>${str}`, 'text/html');
  return doc.body.textContent;
}

方式A:在组件内解码

直接在使用数据的组件里调用函数:

const Question = ({ q }) => {
  return <div>{decodeHtmlEntities(q)}</div>;
};

const Category = ({ type }) => {
  return <div>{decodeHtmlEntities(type)}</div>;
};

const Answer = ({ wrong, right, questionType }) => {
  return (
    <div>
      {questionType === "boolean" && <div> TRUE OR FALSE</div>}
      {questionType === "multiple" && (
        <div>
          {wrong.map((ans, idx) => (
            <div key={idx}>{decodeHtmlEntities(ans)}</div>
          ))}
          <div>{decodeHtmlEntities(right)}</div>
        </div>
      )}
    </div>
  );
};

方式B:获取数据时统一解码

更高效的方式是在获取API数据后,一次性解码所有需要的字段,组件直接使用解码后的数据:

async function getDat() {
  const res = await fetch(path);
  const data = await res.json();
  
  // 统一解码所有字段
  const decodedResults = data.results.map(item => ({
    ...item,
    category: decodeHtmlEntities(item.category),
    question: decodeHtmlEntities(item.question),
    correct_answer: decodeHtmlEntities(item.correct_answer),
    incorrect_answers: item.incorrect_answers.map(ans => decodeHtmlEntities(ans))
  }));
  
  setTrivia(decodedResults);
}

这样组件里不需要额外处理,直接像原来一样渲染即可:

const Question = ({ q }) => {
  return <div>{q}</div>;
};

两种方法对比:

  • 方法1适合快速实现,代码改动最少;
  • 方法2更安全,不会执行任何HTML标签,适合对内容安全性要求高的场景。

内容的提问来源于stack exchange,提问作者Grapes and Cheese

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 14:47:51