Prevent React-native WebView from downloading a PDF

June 09, 2022

Prevent React-native WebView from downloading a PDF

Prevent React-native WebView from downloading a PDF

Issue

This question is relevant to all Android Chrome browsers I think, but in my case I am using the React-native WebView (which is compiling to the native webview in the app).I should add that this works fine on iOS because a URL which points to a PDF just loads that PDF in the browser.

So, I’m wondering whether there’s a way to force the Chrome browser to load a PDF in the browser using a header?

Or, is there a URL that allows you to pass the PDF url in as a param?Some kind of proxy service.

Any ideas?

Solution 1

I solved this issue by using Google Docs to display the given pdf url.Just replace my_pdf_urlwith your pdf url.

https://docs.google.com/gview?embedded=true&url=my_pdf_url

Snack Example

https://snack.expo.dev/z8uGb0fCz

Solution 2 For Expo Users

import { View,Platform,ToastAndroid} from 'react-native'
import React,{useState,useEffect} from 'react'
import axios from 'axios'
import * as FileSystem from 'expo-file-system'
import WebView from 'react-native-webview'
import * as IntentLauncher from 'expo-intent-launcher';

const WebViewCustom = ({RenderLoading,url,CloseStepCallback}) => {
    const [LocalUri, SetLocalUri] = useState(null)
    
    useEffect(() => {
        DownloadFile()
    }, []) 
    const DownloadFile=async()=>{
      try {
        let fileUri;
        let fileName = url.substring(url.lastIndexOf('/')+1);
       const {data,headers} = await axios.get(url, {
         responseType: 'blob'
       });
       let mime= headers['content-type'];
        console.info({fileName,mime}) 
       const fr = new FileReader();
         fr.onload = async () => {
        fileUri = `${FileSystem.documentDirectory}/${fileName}`;
        await FileSystem.writeAsStringAsync(fileUri, fr.result.split(',')[1], {encoding: FileSystem.EncodingType.Base64});
        console.info({fileUri})
        if(Platform.OS === 'ios'){
            SetLocalUri(url)
          }else{
          let cUri = await FileSystem.getContentUriAsync(fileUri);
          console.info(cUri)
          try {
            await IntentLauncher.startActivityAsync('android.intent.action.VIEW', {
              data: cUri,
              flags: 1,
              type: "application/pdf",
           })
           CloseStepCallback();
          } catch (error) {
            console.info({error})
              ToastAndroid.show(
                `No Viewer Application Found`,
                ToastAndroid.LONG
              );
          }
        }
       }    
        fr.readAsDataURL(data);
      } catch (error) {
          console.info(error,'error')
         }
      } 

  return (
    <View style={{flex:1}}> 
        {LocalUri?
            <WebView 
            style={{flex:1}}  
            source={{uri:LocalUri}} />:
        <> 
        {RenderLoading()} 
        </>
        }
    </View>
  )
}

export default WebViewCustom

Written by Manoj Bhardwaj who lives and works in Dharamshala Himachal Pradesh (India). My stackoverflow