React Native Webview中.ttf/.woff字体文件访问报500错误排查
React Native WebView字体文件加载500错误排查与解决
问题现象
在React Native WebView中通过CSS路径加载.ttf、.woff字体文件时返回500错误,但浏览器环境下可正常访问开发服务器上的字体资源(如http://192.168.1.5:19000/assets/dart/assets/fonts/flaticon.woff)。
核心原因
- 路径映射不匹配:CSS中使用的绝对路径
/assets/dart/assets/fonts/...在WebView本地环境中无法正确映射到React Native的资源位置——浏览器的/assets指向开发服务器根目录,但WebView的本地上下文没有这个映射关系。 - 资源打包与解析问题:React Native对本地资源的处理机制和浏览器不同,未正确配置字体资源的打包规则时,WebView无法找到对应文件。
- baseUrl处理错误:代码中手动移除了
/assets前缀,导致WebView的基准路径和资源实际路径脱节,无法解析绝对路径。
解决方案
1. 修正路径引用方式
将CSS中的绝对路径改为相对路径,根据文件层级关系调整:
- 假设文件结构:
index.html→/assets/dart/,flaticon.css→/assets/dart/css/,字体文件 →/assets/dart/assets/fonts/ - 修改CSS中的字体路径:
@font-face { font-family: "Flaticon"; src: url("../assets/fonts/flaticon.eot"); src: url("../assets/fonts/flaticon.eot#iefix") format("embedded-opentype"), url("../assets/fonts/flaticon.woff") format("woff"), url("../assets/fonts/flaticon.ttf") format("truetype"), url("https://tgldcdp.tg.org.au/assets/css/extlib/fonts/flaticon.svg") format("svg"); font-weight: normal; font-style: normal; }
2. 配置React Native字体资源打包
在项目根目录创建/修改react-native.config.js,添加字体资源路径:
module.exports = { assets: ['./assets/dart/assets/fonts/'], };
运行资源链接命令(RN 0.60+可自动链接,低版本需手动执行):
npx react-native link
3. 修正baseUrl处理逻辑
不要移除Asset URI中的/assets前缀,确保基准路径和资源路径匹配:
useEffect(() => { const loadHTMLContent = async () => { try { const assetsUri = Asset.fromModule(require('../../assets/dart/index.html')).uri; const baseUri = assetsUri.split('/index.html')[0]; setBaseUrl(baseUri); fetch(assetsUri) .then(response => response.text()) .then(setHtml); } catch (err) { console.log(err); } }; loadHTMLContent(); }, []);
4. 直接替换为RN资源URI(可选)
如果需要保留绝对路径,可以在加载HTML时将CSS中的字体路径替换为React Native生成的资源URI:
useEffect(() => { const loadHTMLContent = async () => { try { const assetsUri = Asset.fromModule(require('../../assets/dart/index.html')).uri; const baseUri = assetsUri.split('/index.html')[0]; setBaseUrl(baseUri); // 获取字体文件的RN资源URI const fontWoffUri = Asset.fromModule(require('../../assets/dart/assets/fonts/flaticon.woff')).uri; const fontTtfUri = Asset.fromModule(require('../../assets/dart/assets/fonts/flaticon.ttf')).uri; const fontEotUri = Asset.fromModule(require('../../assets/dart/assets/fonts/flaticon.eot')).uri; fetch(assetsUri) .then(response => response.text()) .then(content => { // 替换CSS中的字体路径 content = content.replace('/assets/dart/assets/fonts/flaticon.woff', fontWoffUri); content = content.replace('/assets/dart/assets/fonts/flaticon.ttf', fontTtfUri); content = content.replace('/assets/dart/assets/fonts/flaticon.eot', fontEotUri); setHtml(content); }); } catch (err) { console.log(err); } }; loadHTMLContent(); }, []);
内容的提问来源于stack exchange,提问作者The Bassman
相关产品推荐
相关产品推荐

