React-native-fetch-blob: Loading images fetched with RNFetchBlob from WebView

Created on 25 Nov 2016  路  17Comments  路  Source: wkh237/react-native-fetch-blob

I use RNFetchBlob to download and save images to the RNFetchBlob.fs.dirs.DocumentDir folder like so:

const url = 'http://i.imgur.com/d16lkeR.jpg'
const slashPlusFilename = url.slice(url.lastIndexOf('/'))
const finalFilename = RNFetchBlob.fs.dirs.DocumentDir + slashPlusFilename
const res = await RNFetchBlob.config({ path : finalFilename }).fetch('GET', url, { 'Cache-Control' : 'no-store' })

I later wish to load these images from within a local webapp running in a WebView (just a simple HTML page with some <img ../> tags).

The WebView gives me a 404 but I'm not sure why. I use finalFilename as src.

  • Could it be a permissions problem due to the way the files are created by the library?
  • Is there some flag you need to set to make the files visible to the WebView or something?

I've asked a similar question (without the reference to this library) here, but I think it's more likely to have something to do with this library. For reference here's the other question.

http://stackoverflow.com/questions/40804298/load-local-image-file-from-within-webview

needs feedback needs investigation

Most helpful comment

Figured it out finally! Some notes if anyone else should be in the same pickle later:

const html = `.. <script src="${RNFetchBlob.fs.dirs.MainBundleDir}/bundle.js"></script> ..`
<WebView .. source={{ baseUrl: RNFetchBlob.fs.dirs.DocumentDir, html }} />

bundle.js

This is the (compiled/bundled) code that runs within the WebView.

It is placed under /web in the XCode project and can therefore be loaded as shown above.

Loading images from Documents

This is now the base URL for everything inside the WebView, so anything in Documents can be referenced with ./anything.png.

All 17 comments

@plougsgaard , haven't tried this before, but I think add a file URI scheme file:// to the path might do the trick

@wkh237 I should have said so, but I've tried file:// (and content://) and it doesn't work either.

I'm not familiar with webview, could it because content-security-policy or CORS ?

That's definitely a possibility (CSP) - I'll try getting a hold of an Android phone to test that (won't have the issue if that's what's wrong).

Another alternative way is pass the file's BASE64 string via injectedJavaScript API and use data URI in src 馃槒

Heh, that'll be slow though (through the bridge). 馃槃

Figured it out finally! Some notes if anyone else should be in the same pickle later:

const html = `.. <script src="${RNFetchBlob.fs.dirs.MainBundleDir}/bundle.js"></script> ..`
<WebView .. source={{ baseUrl: RNFetchBlob.fs.dirs.DocumentDir, html }} />

bundle.js

This is the (compiled/bundled) code that runs within the WebView.

It is placed under /web in the XCode project and can therefore be loaded as shown above.

Loading images from Documents

This is now the base URL for everything inside the WebView, so anything in Documents can be referenced with ./anything.png.

Oh my holy S%%T. @plougsgaard if I was in front of you, I would kiss you!. I've been stuck on this for 3 days and got really desperate with it. Your answer it's just marvelous.... it worked perfect thanks to that!
Really, really thank you!

@Ruffeng haha thanks a lot for the (too) kind words! 馃槃

@Ruffeng I felt totally same as you. It was a great help!!! @plougsgaard Thank you soooooooo much!
Anyway I think it'd better know what actually happens with this solution.
In my case, I was able to get my codes work properly with just adding baseUrl like below.
<WebView ... source={{baseUrl: VIDEOS_DIRECTORY_PATH, html: ...}}/>

My app shows video by WebView using html5 video tag both from http url and local files. It usually use Url but when after an user download a video, locally saved video file is used.
The problem was that I could not play local video by specifying local file path.
At this point, your solution did work.

What does baseUrl property acually do?
and why was it ok for my case without adding bundle.js src on script?
Again, Thank you so much

Oh I found it works as well when I put any string in baseUrl property..
I just put empty string like <WebView ... source={{baseUrl: "", html: ...}}/>, it works well too.
What happened with this?

@plougsgaard You are a freaking legend ! How did you find that by yourself ? Finally I can manipulate my images in CSS rather than with gl-react

My image is even not downloading.

const finalFilename =RNFetchBlob.fs.dirs.DocumentDir + "/iamimage.jpeg";
const res = await RNFetchBlob.config({ path: finalFilename }).fetch("GET",
                             NewData.imageUrl,{ "Cache-Control": "no-store" } );

But res show correct path:(data/user/0/com.appname/files/iamimage.jpeg)
And when i want to display, it will display in image component using with file://.
But why its not physical visible at com.appname/files/????

I can not get this working on react-native 0.56.0 and 0.57.0 :/
I'm using a baseUrl and full paths to the image. E.g: /data/user/0/com.app/files/test.jpg

Works for me when using react-native-webview and passing allowFileAccess={true}

The related issue in react-native is: https://github.com/facebook/react-native/issues/21104

Where did you save your html file? Is it in "DocumentDir" directory?

@lourencogui I use source={{ baseUrl: RNFetchBlob.fs.dirs.DocumentDir, html }} to inject the html directly.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

gonglong picture gonglong  路  3Comments

aouaki picture aouaki  路  3Comments

atasmohammadi picture atasmohammadi  路  3Comments

yaronlevi picture yaronlevi  路  4Comments

mykelaballe picture mykelaballe  路  4Comments