从网址加载HTML5
页面时我在该页面的某处获取了pdf,我必须下载该pdf或将其保存为base64
。
这是pdf在HTML代码中的位置。我不能简单地点击“src”网址并获取pdf。
< embed width="100%" height="100%" name="plugin" id="plugin" src="https://myurl.com/fileToOpen.pdf” type="application/pdf" internalinstanceid="8" title="">
任何可以帮助我获取base64
字符串或任何其他方法的JS?
答案 0 :(得分:3)
<强>更新强>
来自他们所说的Docs
Fetch API提供了一个获取资源的接口(包括 整个网络)。任何使用过的人都会觉得很熟悉 的XMLHttpRequest
您还可以使用以下字符串从WKWebview
获取base64字符串 let s = "path = document.getElementById(\"plugin\").src\n" +
"\n" +
"fetch(path).then(function (response) {\n" +
" response.body.getReader().read().then(function(result) {\n" +
" return btoa(String.fromCharCode.apply(null, result.value));\n" +
" }).then(function(b64) {\n" +
" window.webkit.messageHandlers.myInterface.postMessage(b64);\n" +
" });\n" +
"});"
使用以下代码从javascript到Swift 获取base64字符串。 当base64字符串准备好被使用时,我正在使用WKScriptMessageHandler从Javascript 获取回调。在String中,您只需要传递pdf的url,它将执行ajax请求以获取pdf文件,然后将其转换为base64字符串。
import UIKit
import WebKit
class ViewController: UIViewController {
@IBOutlet weak var btnPDF: UIButton!
@IBOutlet weak var webViewParentView: UIView!
var activityIndicator: UIActivityIndicatorView?
var webView: WKWebView!
@objc func didSelect(_ sender: UIView){
let s="var xhr = new XMLHttpRequest();\n" +
"xhr.open(\'GET\', \"https://codingexceptions.com/wkwebview/dummy.pdf\", true);\n" +
"\n" +
"xhr.responseType = \'arraybuffer\';\n" +
"\n" +
"xhr.onload = function(e) {\n" +
" if (this.status == 200) {\n" +
" var uInt8Array = new Uint8Array(this.response);\n" +
" var i = uInt8Array.length;\n" +
" var binaryString = new Array(i);\n" +
" while (i--)\n" +
" {\n" +
" binaryString[i] = String.fromCharCode(uInt8Array[i]);\n" +
" }\n" +
" var data = binaryString.join(\'\');\n" +
"\n" +
" var base64 = window.btoa(data);\n" +
"\n" +
"window.webkit.messageHandlers.myInterface.postMessage(base64);" +
"\n" +
" }\n" +
"};\n" +
"\n" +
"xhr.send();\n"
webView.configuration.userContentController.add(self, name: "myInterface")
webView?.evaluateJavaScript(s, completionHandler: {(string,error) in
print(error ?? "no error")
})
}
func setupWebView(){
webView = WKWebView.init(frame: CGRect(x: 0, y: 0, width: webViewParentView.frame.width, height: webViewParentView.frame.height))
webView.navigationDelegate = self
webViewParentView.addSubview(webView)
activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: .gray)
activityIndicator?.center = self.view.center
self.view.addSubview(activityIndicator!)
webView.load(URLRequest(url: URL(string: "https://codingexceptions.com/wkwebview/index.php")!))
activityIndicator?.startAnimating()
}
override func viewDidLoad() {
super.viewDidLoad()
btnPDF.addTarget(self, action: #selector(self.didSelect(_:)), for: .touchUpInside)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
setupWebView()
}
}
extension ViewController: WKScriptMessageHandler{
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
print("Message received: \(message.name) with body: \(message.body)")
}
}
extension ViewController: WKNavigationDelegate{
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
self.activityIndicator?.stopAnimating()
self.activityIndicator?.removeFromSuperview()
self.activityIndicator = nil
}
}
更新:从@Tarun的回答中指出来自embed标签的源
将行放在字符串变量s 的开头,然后在xhr.open中传递url
var url = document.getElementById("plugin").src
答案 1 :(得分:2)
PS:使用答案作为评论,因为我需要格式化
您应该在webview中执行以下JavaScript
path = document.getElementById("plugin").src
fetch(path).then(function (response) {
response.body.getReader().read().then(function(result) {
return btoa(String.fromCharCode.apply(null, result.value));
}).then(function(b64) {
window.pdf_data = b64;
});
});
然后你可以执行另一个查询来访问window.pdf_data
,假设从javascript执行中获取返回值是可能的吗?
答案 2 :(得分:2)
这个问题有时又被问到, 但是,如果有人用 WKWebView 寻找快速解决方案来下载.pdf或文件管理器上的任何文件,这就是我的最终目的
class WebPortalVC: UIViewController, WKNavigationDelegate,WKUIDelegate, UIDocumentInteractionControllerDelegate,URLSessionDownloadDelegate {
覆盖以下函数,该函数将拦截url,在本例中,我们检查以.pdf和.csv结尾的ulr,并使用文件管理器视图重定向到open以打开。可以查看文件,下载并保存在设备存储中,空投或与其他应用共享
只需添加以下功能并检查。
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
if let url = navigationAction.request.url {
print("fileDownload: check :: \(url)")
let extention = "\(url)".suffix(4)
if extention == ".pdf" || extention == ".csv"{
print("fileDownload: redirect to download events. \(extention)")
DispatchQueue.main.async {
self.downloadPDF(tempUrl: "\(url)")
}
decisionHandler(.cancel)
return
}
}
decisionHandler(.allow)
}
func downloadPDF(tempUrl:String){
print("fileDownload: downloadPDF")
guard let url = URL(string: tempUrl) else { return }
let urlSession = URLSession(configuration: .default, delegate: self, delegateQueue: OperationQueue())
let downloadTask = urlSession.downloadTask(with: url)
downloadTask.resume()
//showHUD(isShowBackground: true); //show progress if you need
}
func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
print("fileDownload: documentInteractionControllerViewControllerForPreview")
return self
}
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
// create destination URL with the original pdf name
print("fileDownload: urlSession")
guard let url = downloadTask.originalRequest?.url else { return }
print("fileDownload: urlSession \(url)")
let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let destinationURL = documentsPath.appendingPathComponent(url.lastPathComponent)
// delete original copy
try? FileManager.default.removeItem(at: destinationURL)
// copy from temp to Document
do {
try FileManager.default.copyItem(at: location, to: destinationURL)
myViewDocumentsmethod(PdfUrl:destinationURL)
print("fileDownload: downloadLocation", destinationURL)
DispatchQueue.main.async {
NBMaterialToast.showWithText(self.view, text: "Download Completed", duration: NBLunchDuration.long)
}
} catch let error {
print("fileDownload: error \(error.localizedDescription)")
}
// dismissHUD(isAnimated: false); //dismiss progress
}
func myViewDocumentsmethod(PdfUrl:URL){
print("fileDownload: myViewDocumentsmethod \(PdfUrl)")
DispatchQueue.main.async {
let controladorDoc = UIDocumentInteractionController(url: PdfUrl)
controladorDoc.delegate = self
controladorDoc.presentPreview(animated: true)
}
}
答案 3 :(得分:-1)
您是要将PDF下载到iPhone还是Mac?通常,无法将PDF直接下载到iPhone,因为iPhone本身无法存储PDF。您需要拥有iBooks或iCloud Drive,然后在另一个窗口中打开PDF,然后手动下载。在下载PDF之前仍需要进行用户交互,这意味着用户必须批准下载。通过将JavaScript注入WKWebView
实例直接下载是不可能的。