ReactJS 无法正常显示字符串中传入的度符号等HTML实体字符
我正在开发的应用会从外部数据源读取数据,比如读取到两段内容:
It is currently
和
°F outside.
应用会将这些内容与环境数据拼接后传入组件解析展示,预期渲染结果为:
It is currently °F outside.
但实际显示的却是:
It is currently °F outside.
我已经尝试过各类度符号编码,应用始终显示原始代码而非对应符号。我也确认index.html的meta标签已经配置了<meta charset="utf-8" />,还尝试过移除字符串绑定的字体改用系统字体,文本是在标准div中渲染的。这只是其中一个示例,我需要实现让来自外部源、包含任意Unicode字符的拼接字符串都能正常渲染对应符号,目前无法定位符号无法正常显示的原因。
这是前端框架默认的HTML实体转义机制导致的问题。所有现代前端框架(React/Vue/Angular等)为了避免XSS注入攻击,默认会把字符串中的特殊字符(比如&、<、>)做转义处理,你从外部数据源拿到的°是HTML实体编码,被转义后会变成&#xb0;,浏览器就不会把它解析成对应的度符号,而是直接显示原始编码文本。你之前检查的charset配置、字体设置都和这个问题无关。
根据你使用的技术栈不同,选择对应方案即可:
1. 通用方案:先解码HTML实体再渲染
如果不想依赖框架的能力,可以自己写一个HTML实体解码函数,处理所有外部来源的字符串后再绑定到视图:
function decodeHtmlEntities(str) { const textarea = document.createElement('textarea'); textarea.innerHTML = str; return textarea.value; }
调用这个函数处理你的拼接字符串,就可以把所有HTML实体编码转为对应的Unicode字符,直接正常渲染。这个方法兼容所有HTML实体,不需要单独处理某一类符号。
2. 框架专属渲染方案
如果你确定外部数据源的内容是安全的,不会有恶意脚本,可以直接用框架提供的「原生HTML渲染」能力:
- Vue:使用
v-html指令绑定内容<div v-html="拼接字符串变量"></div> - React:使用
dangerouslySetInnerHTML属性<div dangerouslySetInnerHTML={{__html: 拼接字符串变量}} /> - Angular:使用
[innerHTML]属性绑定<div [innerHTML]="拼接字符串变量"></div>
如果使用框架的原生HTML渲染能力,一定要确保外部数据源的内容是经过安全校验的,避免恶意脚本注入造成XSS安全漏洞。如果无法保证数据源安全性,优先使用第一种通用解码方案,仅转换HTML实体,不会执行其中的脚本内容。
内容的提问来源于stack exchange,提问作者teh_raab

