(React Native)将本地HTML文件加载到WebView中

z18hc3ub  于 2023-01-02  发布在  React
关注(0)|答案(7)|浏览(226)

我尝试将本地.html文件加载到React Native中的WebView

// load local .html file
const PolicyHTML = require('./Policy.html');

// PolicyHTML is just a number of `1`
console.log('PolicyHTML:', PolicyHTML);

// will cause an error: JSON value '1' of type NSNumber cannot be converted to NSString
<WebView html={PolicyHTML} />

.html文件应作为字符串读取,而不是作为资源代表读取。
如何在React Native中将.html文件加载到WebView中?
顺便问一下,require()的那些资源代表是什么类型的?是number吗?

5jvtdoz2

5jvtdoz21#

试试看:

const PolicyHTML = require('./Policy.html');

<WebView
  source={PolicyHTML}
  style={{flex: 1}}
 />
vwoqyblh

vwoqyblh2#

我遇到了这个职位的搜索加载静态html。
如果您的html代码是使用API等检索的,则可以按以下方式呈现WebView:

<WebView
    originWhitelist={['*']}
    source={{ html: html, baseUrl: '' }}
/>

请注意,如文档中所述,originWhitelist是必需的:
请注意,静态html将需要设置原始白名单,例如设置为["*"]。

igetnqfo

igetnqfo3#

<View style={{flex: 1}}>
    <WebView
      style={{flex: 1}}
      source={require("./resources/index.html")}
    />
</View>

要创建WebView,父级必须具有维度或flex:1.我们可以将WebView设置为flex:1,以便它填充父对象。

tsm1rwdh

tsm1rwdh4#

如果您还需要为本地资产提供服务,则:
1.将所有资产与index.html一起放入android/app/src/main/assets/www(您可以使用gradle任务将它们复制到那里)
1.然后:

var uri = Platform.OS == "android" ?
    "file:///android_asset/www/index.html" :
    "./web/www/index.html"
  return <WebView source={{ uri }} />
    • 对于未测试的iOS,请添加说明,资产应如何存储
d7v8vwbk

d7v8vwbk5#

使用Expo工具并通常使用Expo:

import { WebView } from "react-native-webview";
import { readAsStringAsync } from "expo-file-system";
import { useAssets } from "expo-asset";

export const MusicSheet = () => {
  const [index, indexLoadingError] = useAssets(
    require("../assets/musicsheetview/index.html")
  );

  const [html, setHtml] = useState("");

  if (index) {
    readAsStringAsync(index[0].localUri).then((data) => {
        setHtml(data);
    });
  }

  return (
    <View style={styles.container}>
      <WebView
        onLoad={() => {}}
        source={{ html }}
        onMessage={(event) => {}}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    height: 100,
    display: "flex",
  },
});
zfycwa2u

zfycwa2u6#

试试这个:

  • 将 *. html * 文件添加到项目中。
  • 在要使用WebView组件的文件中写入这些代码行

第一个月

  • <WebView source={OurStoryHTML} style={{flex: 1, marginTop : 44}} />

也许能帮到你。

8iwquhpp

8iwquhpp7#

如果你正在使用资源,一旦项目被构建,项目目录在设备目录上是不同的,你不能简单地通过字符串url引用它们。

博览会

如果使用expo,则必须对每个资产执行require,然后在需要时使用useAssets将它们缓存到设备的本地存储。
useAssets将返回一个包含localUri的对象(这是已经缓存的图像的URI)
然后可以使用localUri并将其作为映像的src

import { useAssets } from 'expo-asset';
    /* . . . */
    const IndexHTML = require('./assets/index.html');
    const myImage = require('./assets/splash.png');

    // url link after image is cached to the device
    const [imgSrc, setImgSrc] = useState('');

    const [image, imerr] = useAssets(myImage);
    const [html, error] = useAssets(IndexHTML);

    const webViewProps = {
        javaScriptEnabled: true,
        androidLayerType: 'hardware',
        originWhitelist: ['*'],
        allowFileAccess: true,
        domStorageEnabled: true,
        mixedContentMode: 'always',
        allowUniversalAccessFromFileURLs: true,

        onLoad: () => {
            console.log(image[0].localUri);
            setImgSrc(image[0].localUri);
        },
        source: {
            html: '<img src="' + imgSrc + '"/>',
        },
    };

    return <WebView {...webViewProps} />
const webViewProps = {
        ...
        source: IndexHTML,
    };
    • 注意:对于expo方法,将找不到IndexHTML中引用的文件**

1.诀窍是将html转换为string literal以利用template strings
1.然后您必须手动要求这些资产中的每一个合并localUrl

  1. require()支持的类型有限,您需要在根文件夹中添加metro.config.js
    1.如果您require()一个.js文件,它将给出错误,因为它将它作为一个模块读取,而不是,变通方法将是bundle your assets
const { getDefaultConfig } = require('expo/metro-config');

const config = getDefaultConfig(__dirname);

config.resolver.assetExts.push(
    // Adds support for asset file types
    'css', 'ppt', 'obj'
);

module.exports = config;
  • 此外,expo可以热重新加载对缓存资产所做的更改。

React Native

如果目录中有android文件夹,请导航到
android > app > build.gradle
然后加上

android {
    /* link assets to the local storage of device */
    sourceSets { 
        main { assets.srcDirs = ['src/main/assets', '../../source/assets/'] } 
        //                      [do not touch,    'relative to your asset'] }
    }
    . . .

最后,您在gradle中链接的相对文件夹可以通过file:///android_asset/访问
例如file:///android_asset/index.html-〉/asset/index.html

return <WebView source={{uri: `file:///android_asset/index.html`}} />
  • 另一方面,您必须重新构建vanilla react才能看到资产的变化.. * 这大约需要20分钟左右 *

备选

一个快速的解决方案是集成一个static server,但这是react-native-static-server的最新分支,只能在vanilla react native中工作。

相关问题