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

React Native WebView无静态服务器加载本地HTML解决方案

问题原因

出现纯文本渲染是三个问题叠加导致的:

  • 代码存在变量拼写错误:定义的资源变量是webviewSOurce,实际传入WebView的是不存在的webSource
  • Android平台下通过Image.resolveAssetSource拿到的资源URI,WebView默认不会按text/html类型解析,直接把源码作为纯文本输出
  • 测试用的HTML不是标准完整文档结构,缺少文档声明和编码配置,部分WebView版本无法自动识别为HTML内容

不需要引入任何本地HTTP/静态服务依赖,以下两种方案都可以直接解决问题:

方案1:直接传入HTML字符串(零额外依赖,兼容性最优)

如果HTML内容体量不大,直接把HTML作为字符串传入WebView是最稳定的实现,完全规避路径和MIME类型问题。

  1. 先把HTML补全为标准结构:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>页面</title>
</head>
<body>
    <div id="main-div">
        <h1>Hello World! I am alive!</h1>
    </div>
</body>
</html>
  1. 页面代码修改如下:
import WebView from 'react-native-webview';
import { View } from 'react-native';

// 直接把HTML内容作为常量,也可以从单独的js/ts文件中导出
const PAGE_HTML = `
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>页面</title>
</head>
<body>
    <div id="main-div">
        <h1>Hello World! I am alive!</h1>
    </div>
</body>
</html>
`;

export default function MyScreen(props) {
    return (
        <View style={{flex: 1}}>
            <WebView
                source={{html: PAGE_HTML}}
                originWhitelist={["*"]}
                style={{
                    width:'100%',
                    minHeight:400
                }}
            />
        </View>
    )
}

这个方案全平台兼容,不需要额外配置,适合绝大多数场景。

方案2:加载独立HTML文件(适合带配套静态资源的场景)

如果HTML内容较多,或者需要关联同目录下的CSS、JS、图片等资源,可以直接加载独立HTML文件,不需要启动本地服务:

  1. 先修改项目根目录下的metro.config.js,让打包工具识别HTML及相关静态资源:
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');

const defaultConfig = getDefaultConfig(__dirname);

const config = {
  resolver: {
    assetExts: [
      ...defaultConfig.resolver.assetExts,
      'html', 'css', 'js', 'png', 'jpg', 'svg' // 把HTML用到的所有静态资源后缀加在这里
    ],
  },
};

module.exports = mergeConfig(defaultConfig, config);
  1. 修改页面代码,处理双平台路径差异,手动指定HTML的MIME类型:
import WebView from 'react-native-webview';
import { View, Platform } from 'react-native';

export default function MyScreen(props) {
    const htmlAsset = require('./src/green.html');
    let source;
    if (Platform.OS === 'ios') {
        // iOS直接传入require返回的资源即可正常解析
        source = htmlAsset;
    } else {
        // Android手动拼接asset路径,强制指定MIME类型为text/html
        source = {
            uri: `file:///android_asset/${htmlAsset.uri.replace('assets://', '')}`,
            mimeType: 'text/html',
            encoding: 'UTF-8'
        };
    }

    return (
        <View style={{flex: 1}}>
            <WebView
                source={source}
                originWhitelist={["*"]}
                allowFileAccess={true}
                allowUniversalAccessFromFileURLs={true}
                style={{
                    width:'100%',
                    minHeight:400
                }}
            />
        </View>
    )
}
  1. 确认green.html是带<!DOCTYPE html>声明的标准完整HTML文档,和方案1中的结构一致即可。
避坑提示
  • 原代码中<View style>属于语法错误,style属性必须传入有效值,建议给外层View加flex:1样式避免布局异常
  • 如果HTML中引用了同目录的静态资源,直接写相对路径即可,Metro打包时会自动处理资源关联
  • 生产环境建议收紧originWhitelist配置,不要长期用通配符*避免安全风险

内容的提问来源于stack exchange,提问作者Super Toptal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 02:33:42