How to read a blob data URL in WKWebView?
Asked Answered
P

1

30

I have a WKWebView, but when I click on a link that has the following URL:

blob:https://www.mycase.com/2963c6c0-24c1-418f-a314-88f7a2dbc713

Nothing happens. Reading the documentation it describes:

The only way to read content from a Blob is to use a FileReader.

So I presume there is no way WKWebView is able to read the Blob itself by some method. As URLSession fails to download the content when you feed it the blob URL.

A solution I came up with myself is to read the blob in JavaScript itself.

var script = ""

script = script + "var xhr = new XMLHttpRequest();"
script = script + "xhr.open('GET', '\(navigationURL)', true);"
script = script + "xhr.responseType = 'blob';"
script = script + "xhr.onload = function(e) { if (this.status == 200) { var blob = this.response; var reader = new window.FileReader(); reader.readAsBinaryString(blob); reader.onloadend = function() { window.webkit.messageHandlers.readBlob.postMessage(reader.result); }}};"
script = script + "xhr.send();"

self.webView.evaluateJavaScript(script, completionHandler: nil);

Then add a script message handler to fetch the content.

let configuration = WKWebViewConfiguration()
configuration.userContentController.add(self, name: "readBlob")

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
    print(message.body)
}

It feels a bit cumbersome to do it like this, is there any other way?

Peralta answered 12/7, 2017 at 18:26 Comment(8)
Did you find any solution for thisCrib
Did you find solution?Optimize
@DarshanMothreja see if this helps you: #61702914Jahveh
For some reason the didReceive message callback does never get called. My blob looks very similar to your example. But your script does not seem to do the job. Can you please show more of your original workaround example ? Thank youLawabiding
In fact, I can change the script to an example-script such as window.webkit.messageHandlers.readBlob.postMessage('test'); and everything works. But your complicated Request-script still does not seem to work. Do you know if it will work for images or videos being downloaded ?? What was your original download type for your code script-example ?Lawabiding
Hello. Your example with script does not work. xhr.onload never called. Maybe you have another way?Dorisdorisa
This has worked in the past (four years ago) if it doesn't know I am curious for a solution too. Sorry I can't help you any further.Peralta
Where is this blob: URL coming from? There's a lot of potential problems with URLs that have "blob:" as a scheme.Erythrocytometer
D
1

an alternative

Using fetch() instead of XMLHttpRequest, since fetch() API is more modern and might provide cleaner syntax for handling blobs.

const url = navigationURL; // Your blob URL
fetch(url)
    .then(response => response.blob())
    .then(blob => {
        const reader = new FileReader();
        reader.onload = () => {
            window.webkit.messageHandlers.readBlob.postMessage(reader.result);
        };
        reader.readAsDataURL(blob); // Consider using DataURL for compatibility
    })
    .catch(e => console.error(e));

One more alternative is considerind encoding it in Base64, which might be more robust for handling in your native code.

Having said the above your solution is still quite good to be sincere.

Dominus answered 30/4 at 5:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.