title: Download image from blob WKWebView without knowing the url
body: <p>I am accessing a website using WKWebView and on that website there is a download button. On Chrome using a laptop that downloads the file, when I click download on the iOS simulator it displays the image in the WKWebView. My goal is to save that image off and display it in a CollectionView later. If I had the URL as <code>https://www.website.com/image.jpg</code> then that would be easy to do, the problem is it is a blob url so the format <code>blob:https://www.website.com/abcd-efgh-ijkl</code>.</p>
  
  <p>I found this link which is somewhat helpful:
  <a href="https://stackoverflow.com/questions/45065085/how-to-read-a-blob-data-url-in-wkwebview">How to read a blob data URL in WKWebView?</a></p>
  
  <p>Here is a slimmed down version of my ViewController:</p>
  
  <pre><code>import UIKit
  import WebKit
  
  class DownloadBlob: UIViewController, WKNavigationDelegate, WKScriptMessageHandler {
  
      lazy var webView: WKWebView = {
          let config = WKWebViewConfiguration()
          config.userContentController.add(self, name: "readBlob")
          let webView = WKWebView(frame: UIScreen.main.bounds, configuration: config)
          webView.navigationDelegate = self
          return webView
      }()
  
      override func viewDidLoad() {
          super.viewDidLoad()
          // Do any additional setup after loading the view, typically from a nib.
  
          let request = URLRequest(url: url!)
          webView.load(request)
      }
  
      func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
          print("Finished")
      }
  
      func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -&gt; Void) {
          print(navigationResponse)
  
          decisionHandler(.allow)
      }
  
      func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -&gt; Void) {
          print(navigationAction)
          let navigationURL = navigationAction.request.url
          if (navigationURL?.absoluteString.contains("blob"))! {
              testDownloadBlob(navigationURL: navigationURL!)
          }
          decisionHandler(.allow)
      }
  
      func testDownloadBlob(navigationURL: URL) {
  
          var script = ""
          script = script + "var xhr = new XMLHttpRequest();"
          script = script + "xhr.open('GET', '\(navigationURL.absoluteString)', true);"
          script = script + "xhr.responseType = 'blob';"
          script = script + "window.webkit.messageHandlers.readBlob.postMessage('making sure script called');"
          script = script + "xhr.onload = function(e) { if (this.status == 200) { var blob = this.response; window.webkit.messageHandlers.readBlob.postMessage(blob); 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) { (results, error) in
              print(results ?? "")
          }
      }
  
      func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
          print(message.name, message.body)
      }
  
  
  }
  </code></pre>
  
  <p>I noticed that the xhr.onload isn't being called at all, but not sure how to fix this. I do, however, get a response with the blob in the decidePolicyFor navigationResponse.</p>
  
  <p>Is there a way to do this to get the image data and save it?</p>