react-native-webview: Unable to load local file on Android
When trying to open a local webpage from tyhe local file system (using file://
) it works on iOS, but on Android we get an error:
Encountered an error loading page:
{
canGoBack: false,
canGoForward: false,
code: -1,
description: "net::ERR_ACCESS_DENIED",
loading: false,
target: 165,
title: "Webpagina niet beschikbaar",
url: "file:///data/user/0/com.twipepocv4/cache/data/36/Page-313.html",
}
This is my code:
<WebView
originWhitelist={['*']}
allowFileAccess={true}
source={{uri: "file:///data/user/0/<myapp>/cache/data/36/Page-319.html"}}
domStorageEnabled={true}
allowUniversalAccessFromFileURLs={true}
allowFileAccessFromFileURLs={true}
/>
I believe this has something to do with AllowFileAccessFromFileURLs but I can’t get it to work. Should any other permission be set?
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 16
- Comments: 29 (2 by maintainers)
Commits related to this issue
- Fixed PDF not rendering on Android Issue was with WebView permissions not being set in time, fixed using https://github.com/react-native-community/react-native-webview/issues/656#issuecomment-5513124... — committed to ALEEF02/Bulletin-Magazine-Mobile-App by ALEEF02 5 years ago
- Workaround for loading local files in Android WebView https://github.com/react-native-community/react-native-webview/issues/656 — committed to sguha00/rn-pdf-reader-js by sguha00 4 years ago
- Workaround for loading local files in Android WebView https://github.com/react-native-community/react-native-webview/issues/656 — committed to xcarpentier/rn-pdf-reader-js by sguha00 4 years ago
- Add props and handle in Android https://github.com/react-native-webview/react-native-webview/issues/656#issuecomment-737182325 — committed to compac-reader/compac-reader by kouki-dan 3 years ago
- Add props and handle in Android https://github.com/react-native-webview/react-native-webview/issues/656#issuecomment-737182325 — committed to compac-reader/compac-reader by kouki-dan 3 years ago
@tjensen is exactly right on the cause. Here’s a more detailed investigation and a workaround that we use. This only applies to Android 10.
Problem
react-native-webview
on Android handles theallowFileAccess
andallowUniversalAccessFromFileURLs
by callingview.getSetings().setAllowFileAccess()
in the Java code: https://github.com/react-native-community/react-native-webview/blob/47e9a0b/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java#L484At the same time, setting
source
callsview.loadUrl()
. This results in a race where ifview.loadUrl()
executes before the security settings are updated, the page-load will fail.Workaround
We don’t load your local file until we’re sure the correct permissions have been set on the WebView.
On the component you have that renders
<WebView source={...}>
:componentDidMount
, set that variable to betrue
renderedOnce
is true:You guys are not doing properly, Proper ways is as follows: First install it using (If not installed), npm install --save react-native-webview // inside project root directory react-native link react-native-webview // it will link WebView with iOS and Android
I hope this will help you guys.
It doesn’t require to use prop “allowFileAccess”, you try above code, it will work perfectly.
I use functional components and hooks and got the solution from @hsource to work by updating the
setRenderedOnce
in a function that I pass to the webview’sonLoad
prop:This issue should reopen
I tried all solutions suggested above, but
ERR_ACCESS_DENIED
problem occurs. In my case, I download and save a file to my app’s cache directory (e.g.file:///data/user/0/.../cache/5f8f.../downloaded.pdf
) and try to open this file using WebView. My WebView code is:On iOS, it works fine. However, on Android, it prints ERR_ACCESS_DENIED. I’ve tried the solution put
renderOnce
state but it did not work for me.Any other solution to solve my problem? Thanks, in advance. If you need more code to investigate, please let me know.
@femiveys
Navigate to node_modules/react-native-webview/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java
Change the following lines:
By default, these props will be false, make it true and you’re good to go. 😃
@mayursarode4 What if your path to the html is dynamic? And you don’t know the exact file path at build.
@Shan7anu said:
While this is not a fix that I would be comfortable putting into my production code, it does point to the underlying problem, which is that the order in which the WebView props are set may not be deterministic. I added
System.out.println
calls to thesetSource
andsetAllowFileAccess
methods in RNCWebViewManager.java (version 6.11.1), and when the WebView failed to load the local file URL, it was clear that thesetSource
method was called beforesetAllowFileAccess
was called, so the page was being loaded before theallowFileAccess
prop was applied.It seems like there needs to be a mechanism to store the prop values but not actually call
loadUrl
/loadDataWithBaseURL
until after all props have been stored and their settings have been applied to theWebSettings
object for the current WebView instance.I only use hooks and no classes, so use useEffect and useCallback in this way! This code works for displaying local HTML pages on both IOS and Android. Important! Pay attention to html: use only html:
import React, { useState, useEffect, useCallback } from ‘react’; import { StyleSheet, View } from ‘react-native’; import FusionCharts from ‘react-native-fusioncharts’; import * as FileSystem from ‘expo-file-system’; import { Asset } from ‘expo-asset’;
… here different code does not concern the main idea of the solution
const [libraryPath, setLibraryPath] = useState(null); const getLibraryPath = useCallback(async () => { const indexHtml = await Asset.fromModule( require(‘…/…/…/…/assets/fusioncharts.html’) ).downloadAsync(); return await FileSystem.readAsStringAsync(indexHtml.localUri); });
useEffect(() => { async function setData() { Promise.all([dataFetch, schemaFetch]).then(async (res) => { setState({ …state, dataJson: res[0], schemaJson: res[1] }); setLibraryPath({ html: await getLibraryPath() }); }); } setData(); }, []);
return (<View style={styles.container}> <View style={styles.chartContainer}> <FusionCharts dataJson={ state.dataJson } schemaJson={ state.schemaJson } type={state.type} width={state.width} height={state.height} dataFormat={state.dataFormat} dataSource={state.dataSource} libraryPath={libraryPath} /> </View> </View>);
It works 50/50. Sometimes my locally storaged html renders and sometimes I get ACCESS_DENIED error. Is there any solution? Also, it works fine with release build, but some problems with access on debug build.
I tried this. But got Empty white screen. I need to render a html page which import local assests and javascript code in it. Enviroment:
Here how I am doing it.
and html file for testing:
So I ran into the same issue. What solved it for me was to add the prop
allowFileAccess
in the WebView (and also don’t forget to ask the permissionREAD_EXTERNAL_STORAGE
)Edit: Okay so this worked on the Android emulators, but it didn’t on real devices, so I’m back to using react-native WebView for now. I tried using all 3 props
allowFileAccess
,allowUniversalAccessFromFileURLs
andallowFileAccessFromFileURLs
but the error persists…@zhouping3 Try above solution by @imran1992 it will help you solve your issue for react-native: 0.60.+ version’s doesn’t require linking for libraries as it have auto linking feature, you just need to install the libraries and build and run the project.
My version details are,
react-native info info Fetching system and libraries information… System: OS: Linux 4.4 Ubuntu 16.04.6 LTS (Xenial Xerus) CPU: (4) x64 Intel® Core™ i5-4440S CPU @ 2.80GHz Memory: 8.86 GB / 15.57 GB Shell: 4.3.48 - /bin/bash Binaries: Node: 12.4.0 - ~/.nvm/versions/node/v12.4.0/bin/node npm: 6.9.0 - ~/.nvm/versions/node/v12.4.0/bin/npm SDKs: Android SDK: API Levels: 21, 22, 23, 25, 26, 27, 28 Build Tools: 21.1.2, 25.0.0, 25.0.2, 25.0.3, 27.0.3, 28.0.2, 28.0.3 System Images: android-25 | Google Play Intel x86 Atom, android-28 | Intel x86 Atom, android-28 |Intel x86 Atom_64 IDEs: Android Studio: 3.4 AI-183.6156.11.34.5692245 npmPackages: react: 16.8.6 => 16.8.6 react-native: 0.60.4 => 0.60.4 npmGlobalPackages: react-native-cli: 2.0.1
I’m not using expo-cli, so don’t know about it
@developeromI89 if you only want to open PDFs you can use ‘react-native-view-pdf’
Or you can use append your WebView url like this:
"https://docs.google.com/gview?embedded=true&url=$url"
This worked with a local uri (only tested in dev) :
Using expo-asset and this trick : https://github.com/react-native-webview/react-native-webview/issues/656#issuecomment-551312436
@yaoonline can you please post the entire code? This seems not working to me. Thanks
Hello 👋, this issue has been opened for more than 2 months with no activity on it. If the issue is still here, please keep in mind that we need community support and help to fix it! Just comment something like still searching for solutions and if you found one, please open a pull request! You have 7 days until this gets closed automatically