如何在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
相关产品推荐
相关产品推荐

