question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

how to save image to Local from WebView

See original GitHub issue

Bug description: i want to save a image from WebView, in browser i can save image by long tap, but it dose not work in react-native-webview, is there a workaround for this?

System:
    OS: macOS 10.15.2
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
    Memory: 47.20 MB / 16.00 GB
    Shell: 5.7.1 - /bin/zsh
  Binaries:
    Node: 11.15.0 - /usr/local/bin/node
    Yarn: 1.21.1 - ~/.yarn/bin/yarn
    npm: 6.7.0 - /usr/local/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  SDKs:
    iOS SDK:
      Platforms: iOS 13.2, DriverKit 19.0, macOS 10.15, tvOS 13.2, watchOS 6.1
    Android SDK:
      API Levels: 21, 23, 26, 27, 28
      Build Tools: 23.0.1, 26.0.1, 28.0.3, 29.0.2
  IDEs:
    Android Studio: 3.5 AI-191.8026.42.35.6010548
    Xcode: 11.3/11C29 - /usr/bin/xcodebuild
  npmPackages:
    react: 16.9.0 => 16.9.0
    react-native: 0.61.5 => 0.61.5

React-Native-WebView: '8.0.2'

similar issue: https://github.com/react-native-community/react-native-webview/issues/63 https://github.com/react-native-community/react-native-webview/issues/644 To Reproduce:

Expected behavior:

Screenshots/Videos:

Environment:

  • OS:
  • OS version:
  • react-native version:
  • react-native-webview version:

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:9
  • Comments:16

github_iconTop GitHub Comments

5reactions
MujtabaFRcommented, Apr 20, 2020

For IOS I just enabled allowsLinkPreview For Android I used some javascript with injectedJavaScript to handle longpress on images to download

injectedJavaScript={`
      var longPressDuration = 750;
      var confirmationMessage = "Would you like to download this image ?";

      var imgsItems = document.getElementsByTagName('img');
      var divsItems = document.getElementsByTagName('div');

      if (imgsItems.length == 1 && divsItems.length == 0) { // if the page contains only the image, directly download it then go back
            var url = imgsItems[0].getAttribute('src');
            if (url && url != '' && url.startsWith('http')) {
                var link = document.createElement('a');
                link.href = url;
                link.download = 'Download.jpg';
                document.body.appendChild(link);
                link.click();
                document.body.removeChild(link);

                setTimeout(() => {
                  window.history.back();
                }, 750);

            }

      } else { // for normal pages
          for (var i = 0, j = imgsItems.length; i < j; i++) {
                var node = imgsItems[i];
                var longpress = false;
                var presstimer = null;
                var longtarget = null;

                var cancel = function(e) {
                    if (presstimer !== null) {
                        clearTimeout(presstimer);
                        presstimer = null;
                    }

                    this.classList.remove("longpress");
                };

                var click = function(e) {
                    if (presstimer !== null) {
                        clearTimeout(presstimer);
                        presstimer = null;
                    }

                    this.classList.remove("longpress");

                    if (longpress) {
                        return false;
                    }

                    // alert("press");
                };

                var start = function(e) {
                    console.log(e);

                    if (e.type === "click" && e.button !== 0) {
                        return;
                    }

                    longpress = false;

                    this.classList.add("longpress");

                    if (presstimer === null) {
                        presstimer = setTimeout(function() {

                            // alert("longpress");

                            var url = e.target.getAttribute('src');
                            if (url && url != '' && url.startsWith('http') && confirm(confirmationMessage)) {
                                var link = document.createElement('a');
                                link.href = url;
                                link.download = 'Download.jpg';
                                document.body.appendChild(link);
                                link.click();
                                document.body.removeChild(link);
                            }

                            longpress = true;
                        }, longPressDuration);
                    }

                    return false;
                };

                node.addEventListener("mousedown", start);
                node.addEventListener("touchstart", start);
                node.addEventListener("click", click);
                node.addEventListener("mouseout", cancel);
                node.addEventListener("touchend", cancel);
                node.addEventListener("touchleave", cancel);
                node.addEventListener("touchcancel", cancel);
          }
      }
`}
1reaction
tuoxianspcommented, Mar 25, 2022

I’m using expo-media-library, it works well with none-expo-managed project.

  1. Install dependences: https://docs.expo.dev/versions/latest/sdk/media-library/#installation https://docs.expo.dev/versions/latest/sdk/filesystem/#installation
import * as FileSystem from 'expo-file-system';
import * as MediaLibrary from 'expo-media-library';
  1. Convert image to base64, then send it to ReactNative thread with postMessage:
window.ReactNativeWebView.postMessage(
  JSON.stringify({
    type: 'SAVE_IMAGE',
    data: base64imageStr
  })
)
  1. Handle received image data in onMessage:
<Webview 
  onMessage={async () => {
    const msg = JSON.parse(event.nativeEvent.data);
    if (msg.type === 'SAVE_IMAGE') {
      // save image here
    }
  }}
/>
  1. Request permission to access album, then save image
const permission = await MediaLibrary.requestPermissionsAsync();
if (permission.granted) {
  const base64Code = base64ImageUrl.split('data:image/png;base64,')[1]; 
  const filename = FileSystem.cacheDirectory + 'temp.png';

  await FileSystem.writeAsStringAsync(filename, base64Code, {
    encoding: FileSystem.EncodingType.Base64,
  });

  await MediaLibrary.saveToLibraryAsync(filename);
} else {
  // handle permission disallowed case 
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

how to save images displayed in webview? - android
I want to save the images displayed in webview into local storage, and webview should have cached the images it displays ,how can...
Read more >
how to save image to Local from WebView #1107 - GitHub
Bug description: i want to save a image from WebView, in browser i can save image by long tap, but it dose not...
Read more >
Webview - Right click to save image | B4X Programming Forum
B4A Library Webview - Right click to save image · 1) Include Contextual in your project. · 2) Declare some variable as Contextual...
Read more >
Webview API - Visual Studio Code
Controlling access to local resources ... Webviews can control which resources can be loaded from the user's machine with localResourceRoots option.
Read more >
WebView - Android Developers
Saving passwords in WebView will not be supported in future versions. ... Modifies the input matrix such that it maps view-local coordinates to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found