Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I download through WebView using react-native?

I'm using a WebView and I want to let the person download through the WebView. It's a simple WebView that have a link to download a zip file.

Can I do using the webview? (Like Chrome)

at least I want to get the listener when the user try to download the file though the WebView.

like image 742
Siloé Bezerra Bispo Avatar asked Sep 17 '18 11:09

Siloé Bezerra Bispo


People also ask

How do I get data from react-native in Webview?

Create a function called webviewRef and attach it to the WebView component. Next, create a function called sendDataToWebView and add the code below to it. Inside the “script” tag, use window. addEventListener to listen to the event from the React Native app.

Can I use Webview in react-native?

WebViews offer developers opportunities to render any web components in a React Native application. A web component can be anything from a whole webpage/application or just a simple HTML file. The package react-native-webview makes it super simple to embed WebViews into your React Native apps!


1 Answers

I did on this way, to download a file we need two steps, fetch the bits and create a file on device, in this example I'm downloading any .zip file when the url have a .zip:

I'm using :

import RNFetchBlob from 'rn-fetch-blob';
var RNFS = require('react-native-fs');

and using the WebView like this:

<WebView
    source={{ uri: "http://myinitialurl.com.br/arquivos/" }}
    style={{}}
    startInLoadingState={true}
    allowUniversalAccessFromFileURLs={true}
    javaScriptEnabled={true}
    mixedContentMode={'always'}
    onNavigationStateChange={(result) => this.handleUrlWithZip(result)}
/>

and:

handleUrlWithZip(input) {

    //check if have another download
    if (this.state.downloadStart == true || input.url.toLowerCase().includes('.zip') == false) {
      return;
    } else {
      this.setState({ downloadStart: true, showModalLoading: true })
    }

    const directoryFile = RNFS.ExternalStorageDirectoryPath + '/DownloadFile/';

    //Creating folder
    if (RNFS.exists(directoryFile)) {

      RNFS.unlink(directoryFile)
        .then(() => {
          console.log('FOLDER/FILE DELETED');
        })
        // `unlink` will throw an error, if the item to unlink does not exist
        .catch((err) => {
          console.log('CANT DELETE', err.message);
          this.setState({ showError: true })
        });

      RNFS.mkdir(directoryFile)
    }

    //If folder is created
    if (input) {
      //Verifing if the url have a .zip file
      if (input.url.toLowerCase().includes('.zip')) {
        const urlDownload = input.url;

        let fileName;
        try {
          fileName = urlDownload.substr(urlDownload.lastIndexOf('/')).replace('.zip', '') + '.zip';
        } catch (e) {
          console.log(e);
          fileName = 'example.zip'
        }

        console.log('URL = ' + urlDownload)

        //Downloading the file on a folder
        let dirs = directoryFile + '/' + fileName;
        RNFetchBlob
          .config({
            // response data will be saved to this path if it has access right.
            path: dirs
          })
          .fetch('GET', urlDownload, {
            //some headers ..
          })
          .progress((received, total) => {
            console.log('progress', received / total)
          })
          .then((res) => {
            // the path should be dirs.DocumentDir + 'path-to-file.anything'
            console.log('The file saved to ', res.path())

            //Acabou o download do arquivo
            this.setState({
              downloadStart: false, showModalLoading: false,
              showFileExplorer: true, startFolder: directoryFile
            })
          })
      }
    }
  }
like image 183
Siloé Bezerra Bispo Avatar answered Oct 02 '22 23:10

Siloé Bezerra Bispo