问题
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