WKWebView: How to handle BLOB URL

让人想犯罪 __ 提交于 2020-05-17 06:43:09

问题


I have my wkweview when I click on a file to download it I have a popup writing:

"No application configured to open the URL blob:https// ..."

I tried to register a custom URL scheme blob to wkwebview, the application crash saying that this scheme is already supported by default.

However when I click on the file the delegate is not called:

func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void)

So I can't even know when a blob url is clicker to try to download the file by injecting javascript

My application is for macOS


回答1:


Note that this is a really roundabout hack. Scan all href and replace any blob urls detected with datauri. EDIT: updated to show it running

function blobToDataURL(blob, callback) {
    var a = new FileReader();
    a.onload = function(e) {callback(e.target.result);}
    a.readAsDataURL(blob);
}
// not sure what elements you are going to intercept:
document.querySelectorAll('a').forEach(async (el)=>{
   const url = el.getAttribute('href');
   if( url.indexOf('blob:')===0 ) {
       let blob = await fetch(url).then(r => r.blob());
       blobToDataURL(blob, datauri => el.setAttribute('href',datauri));
   }
});

b=new Blob([new Int8Array([1,2,3,4,5,6,7,8,9,10]).buffer]);
test.href=URL.createObjectURL(b);
b=new Blob([new Int8Array([31,32,33,34,35]).buffer]);
test1.href=URL.createObjectURL(b);
b=new Blob([new Int8Array([51,52,53,54]).buffer]);
test2.href=URL.createObjectURL(b);



function blobToDataURL(blob, callback) {
    var a = new FileReader();
    a.onload = function(e) {callback(e.target.result);}
    a.readAsDataURL(blob);
}

document.addEventListener('click', function(event) {
  event.preventDefault();
  if ( event.target.matches('a[href^="blob:"]') )
     (async el=>{
       const url = el.href;
       const blob = await fetch(url).then(r => r.blob());
       blobToDataURL(blob, datauri => el.href=datauri);
     })(event.target);
});

// not sure what elements you are going to intercept:
/*document.querySelectorAll('a').forEach(async (el)=>{
   const url = el.href;
   if( url.indexOf('blob:')===0 ) {
       let blob = await fetch(url).then(r => r.blob());
       blobToDataURL(blob, datauri => el.href=datauri);
   }
});*/
<a id="test">test</a>
<a id="test1">test</a>
<a id="test2">test</a>

Example of data uri conversion on click:

b=new Blob([new Int8Array([1,2,3,4,5,6,7,8,9,10]).buffer]);
test.href=URL.createObjectURL(b);
b=new Blob([new Int8Array([31,32,33,34,35]).buffer]);
test1.href=URL.createObjectURL(b);
b=new Blob([new Int8Array([51,52,53,54]).buffer]);
test2.href=URL.createObjectURL(b);



function blobToDataURL(blob, callback) {
    var a = new FileReader();
    a.onload = function(e) {callback(e.target.result);}
    a.readAsDataURL(blob);
}

document.addEventListener('click', function(event) {
  if ( event.target.matches('a[href^="blob:"]') ) {
     event.preventDefault();
     (async el=>{
       const url = el.href;
       const blob = await fetch(url).then(r => r.blob());
       blobToDataURL(blob, datauri => window.open(el.href=datauri,el.target||'_self'));
     })(event.target);
   }
});

// not sure what elements you are going to intercept:
/*document.querySelectorAll('a').forEach(async (el)=>{
   const url = el.href;
   if( url.indexOf('blob:')===0 ) {
       let blob = await fetch(url).then(r => r.blob());
       blobToDataURL(blob, datauri => el.href=datauri);
   }
});*/
<a id="test">test</a>
<a id="test1">test</a>
<a id="test2">test</a>


来源:https://stackoverflow.com/questions/61702414/wkwebview-how-to-handle-blob-url

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!