WKWebView不支持blob协议文件的下载,使用js注入,让js代码去下载,完成后将数据返回原生。
blob地址样式:blob:http://192.168.4.254:8080/9994c148-85f7-41fe-aa4c-47b5a91f4868
拿图片举例
- 配置webview,这里的注册名称"readBlob"需要和前端确定统一,js是通过这个方法名称和webview通信的。
let configuretion = WKWebViewConfiguration()
configuretion.preferences.minimumFontSize = 10.0//设置最小字体
configuretion.preferences.javaScriptEnabled = true//打开js交互
configuretion.preferences.javaScriptCanOpenWindowsAutomatically = false//在iOS上默认为NO,表示不能自动通过窗口打开
let userContentController = WKUserContentController()
userContentController.add(self, name: “readBlob”)
configuretion.userContentController = userContentController
- 注入js代码,这里需要注意的是,需要等待webview加载完成后,才可以注入js代码,否则无效。
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print("加载完成")
//下载blob协议文件注入js代码
if let loadUrl = webView.url?.absoluteString {
if (loadUrl.contains("blob:")) && (loadUrl.substring(start: 0, 5) == "blob:") {
let str = "var xhr = new XMLHttpRequest();" +
"xhr.open('GET', '\(loadUrl)', true);" +
"xhr.responseType = 'blob';" +
"xhr.setRequestHeader('Content-type', 'text/plain');" +
"xhr.onload = function(e) {" +
"if (this.status == 200) {" +
"var blob = this.response;" +
"var reader = new FileReader();" +
"reader.readAsDataURL(blob);" +
"reader.onloadend = function() {" +
"window.webkit.messageHandlers.readBlob.postMessage(reader.result);" +
"}" +
"}" +
"};" +
"xhr.send();"
webView.evaluateJavaScript(str, completionHandler: nil)
}
}
}
注意js代码中的"reader.readAsDataURL(blob);"是将blob文件转成base64格式返给webview的。原生需要处理一下,转成图片。
- 接收js返回的数据,转成文件。
//获取js下载完成后将base64格式数据传给webview
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if message.name == "readBlob" {
//print(message.body)//base64类型
var base64String = ""
if let str = message.body as? String {
base64String = str.replacingOccurrences(of: " ", with: "")//去除空格
base64String = base64String.replacingOccurrences(of: "\r", with: "")//去除回车符
base64String = base64String.replacingOccurrences(of: "\n", with: "")//去除换行符
//有前缀,例如data:image/png;base64, 则去除(文件格式自行添加)
base64String = base64String.replacingOccurrences(of: "data:image/png;base64,", with: "")
base64String = base64String.replacingOccurrences(of: "data:image/jpg;base64,", with: "")
base64String = base64String.replacingOccurrences(of: "data:image/jpeg;base64,", with: "")
base64String = base64String.replacingOccurrences(of: "data:image/gif;base64,", with: "")
let base64ImageData = NSData.init(base64Encoded: base64String, options: .ignoreUnknownCharacters)
if let imgData = base64ImageData as Data? {
let img = UIImage.init(data: imgData)
if img != nil {
//将图片保存至相册
UIImageWriteToSavedPhotosAlbum(img!, nil, nil, nil)
print("保存图片成功")
}
}
}
}
}