在iOS 8及更高版本中运行的应用中,使用WKWebView类而不是使用UIWebView。
因此,我用一个闪亮的新UIWebView
替换了我的旧WKWebView
。但我认为这是一个简单的练习(简单地交换类并替换委托方法),结果却是一团糟。
使用
加载HTML字符串时loadHTMLString(String, baseURL: URL?)
网页视图加载并呈现纯HTML,但它不会加载htmlString
中引用的任何图片或CSS文件。
仅在真实设备上发生 ! 在Simultor中,所有引用的资源都已正确加载。
我在视图控制器类中定义了一个简单的htmlString
:
let imageName = "image.png"
let libraryURL: URL // The default Library URL
var htmlString: String {
return "<html> ... <img src=\"\(imageName)\" /> ... </html>"
// "..." represents more valid HTML code incl. header and body tags
}
图像存储在根库文件夹中,因此其URL为:
let imageURL = libraryURL.appendingPathComponent(imageName)
现在我将htmlString
加载到网络视图中:
webView.loadHTMLString(htmlString, baseURL: libraryURL)
即使baseURL
设置正确,也不会加载图像。
也许WKWebView
在解析相对路径时遇到问题,所以我的第一个想法是在HTML字符串中使用绝对路径。
→❌不起作用。
another SO post的两个答案建议使用
loadFileURL(URL, allowingReadAccessTo: URL)
而不是loadHTMLString(...)
适用于iOS 9+
→✅有效。
但是,我无法使用解决方案2,因为我的HTML文件已加密,并且解密的文件不得存储在磁盘上。
有没有办法使用WKWebView
的
loadHTMLString(String, baseURL: URL?)
功能?或者仍然是iOS 9 +中的错误?
(我简直不相信Apple提供并建议使用无法从HTML字符串中加载任何本地Web内容的Web视图?!)
答案 0 :(得分:11)
如果不看一下你的实际项目,很难给出一些肯定的肯定建议。
然而:
class ViewController: UIViewController {
var webView = WKWebView()
override func viewDidLoad() {
super.viewDidLoad()
webView.translatesAutoresizingMaskIntoConstraints = false
let views = [
"webView" : webView
]
view.addSubview(webView)
var constraints = NSLayoutConstraint.constraintsWithVisualFormat("H:|[webView]|", options: [.AlignAllLeading, .AlignAllTrailing], metrics: nil, views: views)
constraints.appendContentsOf(NSLayoutConstraint.constraintsWithVisualFormat("V:|[webView]|", options: [.AlignAllTop, .AlignAllBottom], metrics: nil, views: views))
NSLayoutConstraint.activateConstraints(constraints)
let path = NSBundle.mainBundle().pathForResource("ios - WKWebView fails to load images and CSS using loadHTMLString(_, baseURL_) - Stack Overflow", ofType: "htm")
let url = NSURL(fileURLWithPath: path!)
webView.loadHTMLString(try! String(contentsOfURL: url), baseURL: url.URLByDeletingLastPathComponent)
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
我认为这里的关键点是baseUrl
参数,您应该正确设置它。在我的情况下,我使用了没有最后路径组件的html网址 - 例如包含文件夹。这适用于设备和设备。模拟器 - 检查设备快照。我已将示例项目上传到https://github.com/soxjke/WKWebViewTest,因此您可以查看一下(我已从git中删除了代码签名信息)
所以,回顾 - 方法是有效的,功能是有效的,只是你做错了。为了帮助您解决您的解决方案的问题,我将添加一些建议:
1.请记住,模拟器文件系统不区分大小写,设备文件系统区分大小写。因此,如果你的html中的文件名是小写的 - 这将不适用于设备。 8fFsD.png != 8ffsd.png
2.请记住,在复制资源时,XCode会忽略您的文件夹结构。因此,如果您的html具有<img src="./img/1.png">
并且您的XCOde项目具有类似
test.htm
img/
1.png
2.png
构建后它将被展平,因此test.htm和1.png和2.png将位于同一级别
test.htm
1.png
2.png
我几乎可以肯定,在你验证了这两个假设后,你会得到这个方法。
答案 1 :(得分:3)
您应该能够使用WKWebViews和您已经找到的功能使用本地图像和CSS文件(以及JavaScript文件)。我的猜测是问题出在你的baseURL
变量上。
更新7.5.2017:
我已经完全更新了我another SO answer的代码,这些代码曾经与我的答案相关联。我有loadHTMLString()
和.loadFileURL()
答案 2 :(得分:2)
你可以对图像进行base64编码......我知道这有效。不确定它是否适合您的用例。
有点好笑,我只是遇到了相反的问题 - 从base64编码转移到图像文件。
答案 3 :(得分:2)
就个人而言,我不得不切换到使用XWebView,因为WKWebView的开箱即用行为不允许加载本地文件。 XWebView通过在后台加载本地Web服务器并通过它引导本地流量来欺骗它。 (XWebView基于WKWebView的顶部)
似乎有点矫枉过正,但这就是我最终要做的事情。
答案 4 :(得分:2)
我今天遇到了这个问题,我找到了解决方法,并可能是原因:
loadHTMLString(String, baseURL: URL?)
据我所知,此功能不允许渲染的HTML访问本地媒体,这是因为存在注入风险,这可能允许渲染的HTML访问和操纵本地文件系统。使用html字符串,它可以来自任何地方或任何人。
loadFileURL(URL, allowingReadAccessTo: URL)
使用此功能,可以将WKWebview指向FileManager中的html文件,并指向带有“ allowingReadAccessTo”的文件夹。由于html存储在FileManager中,因此它将允许呈现的HTML访问本地存储的媒体。
如果由于某种原因(我假设您确实没有)将html文件存储在本地,则可以将html字符串写入.html文件,然后指向该文件的URL。但是,这只是在破坏苹果的保护,因此后果自负(不要这样做)。
这只是对我有用的解决方案,也是我对为什么会遇到问题的理解。
编辑#1:错别字。
编辑#2:此后我发现了另一个细微差别,当说明“ allowingReadAccessTo:” URL时,如果HTML本身需要访问父文件夹(即.css,.js文件)中的内容,则需要指定父文件夹(不一定是HTML本身的位置),这也将隐式允许根据需要访问子文件夹。对我而言,此问题仅在物理设备上才明显,在模拟器中运行时似乎没有影响,这可能是模拟器和物理设备上的权限工作方式之间的另一个差异。
答案 5 :(得分:1)
我也一直在试验这个,但有类似的限制,问题似乎是除非baseURL
引用应用程序包,否则不会解析路径。例如,如果您在应用程序的文档中有某些内容,则它不起作用。
编辑:我已为此rdar://29130863
提交了雷达答案 6 :(得分:1)
我知道这已经很老了,但是我遇到了完全相同的问题,花了我数小时的试验,甚至发现这个线程也有相同的问题(Xamarin Forms App)
我的问题是:将远程HTML内容解析为字符串,并添加本地保存的图像(也动态下载,该应用程序无资源)。在模拟器上,所有工具都可以正常工作,但是在手动设备上,本地图像没有显示(也没有显示?或任何表示错误的内容,只是空白帧)。 Xamarin Webview还提供了“ BaseURL”选项,该选项无济于事,也不能在自定义iOS wkWebView上使用BaseURL。
Scott上面指出的唯一可行的解决方案是将HTML写入文件,然后使用“ LoadFileUrl”功能并允许对基本目录的读取访问。这也适用于HTML中图像的绝对文件路径(不仅相对于basedir,而且当然是basedir中的某个地方)。
我用于加载Web和本地内容的自定义Webview渲染器现在看起来像这样:
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) {
base.OnElementPropertyChanged(sender, e);
NSUrl baseURL = new NSUrl(App.dirNews, true);
string viewFile = Path.Combine(App.dirNews, "view.html");
NSUrl fileURL = new NSUrl(viewFile, false);
switch (e.PropertyName) {
case "Url":
System.Console.WriteLine("--- Loading Web page ---");
System.Console.WriteLine("--- " + Element.Url + " ---");
NSUrlRequest myRequest = new NSUrlRequest(new NSUrl(Element.Url), NSUrlRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData, 120);
Control.LoadRequest(myRequest);
break;
case "HTML":
System.Console.WriteLine("--- Showing HTTP content ---");
File.WriteAllText(viewFile, Element.HTML, System.Text.Encoding.UTF8);
Control.LoadFileUrl(fileURL, baseURL);
break;
}
}
答案 7 :(得分:0)
我能够重现类似的问题。除了我的app服务器之外,WKWebView特别加载我的图像。
对于不受SSL保护的服务器(http而不是https),您可以按以下方式设置info.plist
:
App Transport Security Settings
- Allow Arbitrary Loads in Web Content (Set to YES)
- Allow Arbitrary Loads (Set to YES)
问题实际上是在服务器中。服务器应用程序是:
"http://IP-or-domain/uploads/file.jpg"
更改为"../../uploads/file.jpg"
- 或 -
"http://localhost/uploads/file.jpg"
或 "http://127.0.0.1/uploads/file.jpg"
,而不是 "http://YOUR-SERVER-IP-ADDRESS/uploads/file.jpg"
在这些情况下,实际设备无法定位图像。这仅适用于iOS模拟器,因为虚拟设备与服务器和开发机器相同。它可以显示LOCALHOST
和127.0.0.1
。
在我的服务器中,我使用的是富文本编辑器(TinyMCE),它会在检测到它是同一个源后自动删除IP地址。
答案 8 :(得分:0)
尝试使用以下方法创建baseURL
:
let baseURL = URL(fileURLWithPath: "#path#")
代替:
let baseURL = URL(string: "#path#")
主要区别在于,第一种方法在路径之前添加file://
前缀。
答案 9 :(得分:0)
使用UIWebview时,我使用baseURL作为
let baseUrl = NSURL(string: Bundle.main.path(forResource: "cms", ofType: "html")!)! as URL
webView.loadHTMLString(bodyPage, baseURL: baseUrl)
但是对于WKWebView,我使用baseURL作为
let baseUrl = Bundle.main.bundleURL
webView.loadHTMLString(bodyPage, baseURL: baseUrl)
这对我有用。
答案 10 :(得分:0)
WKWebView 可以从 NSTemporaryDirectory 加载图片或 css 文件,所以你可以将你的文件复制到 NSTemporaryDirectory,然后加载它。它在 iOS 14 上对我有用!看到这个问题。 ios-wkwebview-loadhtmlstring-baseurl-fails-to-load-images-and-read-css