react native webview load from device local file system

后端 未结 5 1160
萌比男神i
萌比男神i 2020-12-07 21:08

I\'m trying to load .html, .js, .css files from device\'s local file system into React Native WebView component. I was able to get the

相关标签:
5条回答
  • 2020-12-07 21:48

    In react native it is now possible to require an HTML file and use it as the source for the web view like this (the path is relative to the react-native file you use it in):

    const webapp = require('./webapp/index.html');
    

    and the use it in the WebView like this:

    <WebView source={webapp} />
    

    Unfortunately this does not load CSS and JavaScript files, that are referenced in the HTML. A solution could be, to write all the CSS and JS inline (e.g. by using a build process).

    0 讨论(0)
  • 2020-12-07 21:54

    I was able to include html5/javascript into project by using { html: , baseUrl: } as source. But to be frank, it's more like a lucky shot.

    <WebView source={{ html: HTML, baseUrl: 'web/' }} />

    I have index.html, which require pano2vr_player.js and pano.xml to make this code work.

    const HTML = `
    <html>
    	<head>
    		<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
    		<meta http-equiv="X-UA-Compatible" content="IE=edge" />
    		<title></title>
    		<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0" />
    		<meta name="apple-mobile-web-app-capable" content="yes" />
    		<meta name="apple-mobile-web-app-status-bar-style" content="black" />
    		<meta name="mobile-web-app-capable" content="yes" />
    		<style type="text/css" title="Default">
    			body, div, h1, h2, h3, span, p {
    				font-family: Verdana,Arial,Helvetica,sans-serif;
    			}
        </style>
    	</head>
    	<body>
    		<script type="text/javascript" src="pano2vr_player.js">
    		</script>
    		<div id="container" style="width:100%;height:100%;">
    		<br>Loading...<br><br>
    		This content requires HTML5 with CSS3 3D Transforms or WebGL.
        </div>
    		<script type="text/javascript">
    			// create the panorama player with the container
    			pano=new pano2vrPlayer("container");
    		  window.addEventListener("load", function() {
    			  pano.readConfigUrlAsync("pano.xml");
    		  });
    		</script>
    	</body>
    </html>`;
    
    class PanoView extends Component {
    
      render() {
        return (
          <View>
            <WebView
              style={{ flex: 1, width: 1024, height: 768 }}
              source={{ html: HTML, baseUrl: 'web/' }}
              javaScriptEnabledAndroid={true} />
          </View>
        );
      }
    }

    And finally add files/folder ('/web' same as baseUrl) to XCode project

    And it works! But I'm not sure how...

    0 讨论(0)
  • 2020-12-07 21:55

    Place this script in any file of ReactNative or your code, recomended to first or top index file. And it will fix problem, tested on RN0.39

    import { Platform } from 'react-native';
    import { setCustomSourceTransformer } from 'react-native/Libraries/Image/resolveAssetSource';
    
    setCustomSourceTransformer(function (resolver) {
    
      if (Platform.OS === 'android'
        && !resolver.serverUrl
        && !resolver.bundlePath
        && resolver.asset.type === 'html') {
        resolver.bundlePath = '/android_asset/';
      }
    
      return resolver.defaultAsset();
    });
    
    0 讨论(0)
  • 2020-12-07 22:09

    You may have to wrap your own Native Module to do this. React Native's WebView uses UIWebView, for info on loading a local file take a look here: https://gist.github.com/amster/9160860

    However it is recommended you use WKWebView, you can wrap one yourself relatively easily. There is currently a repo that is WIP: https://github.com/qrush/react-native-wkwebview

    Accomplishing loading local resources using WKWebView can be found in this answer: https://stackoverflow.com/a/28676439/398136

    0 讨论(0)
  • 2020-12-07 22:10

    I stumbled upon the same issue and, after running in circles for hours trying all sorts of solutions, I finally solved it by following this tutorial. Major kudos to the author.

    In the article there's some extra info which is a bit outdated, so here's the concise version instead:

    • create a folder in your main project root (e.g. /html);
    • put all of your files in a folder (e.g. Web, with index.html being your WebView entrypoint), give it a .bundle extension (e.g. Web.bundle), and place it into /html;

    Now you have to add these files to the project so they are recognized and bundled together in your next build, this process is done differently in iOS and Android:

    • iOS: open your project in Xcode, drag n drop Web.bundle into the project's main folder, and confirm the dialog with the "Copy items if needed" option left unchecked;
    • Android: open /android/app/build.gradle and add:
    android {
      ...
      sourceSets { 
        main { assets.srcDirs = ['src/main/assets', '../../html'] } 
      }
    }
    

    Now rebuild your project from scratch to have your changes take effect.

    In your WebView file, calculate the path to index.html and feed it to the WebView:

    const sourceUri = (Platform.OS === 'android' ? 'file:///android_asset/' : '')
        + 'Web.bundle/index.html';
    
    return (
      <WebView
        source={{ uri: sourceUri }}
        originWhitelist={['*']}
        javaScriptEnabled={true}
        allowFileAccess={true}
      />
    );
    

    This will load your index.html and all of its js and css files, as long as they're included in the bundle.

    0 讨论(0)
提交回复
热议问题