WKWebView无法使用loadHTMLString(_,baseURL :)加载图像和CSS

2020/12/10 13:52 · ios ·  · 0评论

苹果的建议

在运行于iOS 8及更高版本中的应用程序中,请使用WKWebView类,而不要使用UIWebView。

因此,我UIWebView用闪亮的新旧纸代替了旧的旧WKWebView但是我认为这是一个简单的练习(只需交换类并替换委托方法),结果真是一团糟。

问题

当我使用加载HTML字符串时

loadHTMLString(String, baseURL: URL?)

网络视图会加载并呈现纯HTML,但不会加载内引用的任何图像或CSS文件htmlString

仅在真实设备上发生

在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到Web视图中:

webView.loadHTMLString(htmlString, baseURL: libraryURL)

即使baseURL设置正确,它也不会加载图像

解决方案的想法

  1. WKWebView解决相对路径可能有问题,所以我的第一个想法是在HTML字符串内使用绝对路径

    →❌不起作用。

  2. 另一则SO帖子的两个答案建议在iOS 9+中使用
    loadFileURL(URL, allowingReadAccessTo: URL)

    代替
    loadHTMLString(...)工作。

    →✅可以。

但是,我无法使用解决方案2,因为我的HTML文件已加密,并且解密后的文件一定不能存储在磁盘上。

有没有什么办法来加载本地资源,如使用图片和样式WKWebView

loadHTMLString(String, baseURL: URL?)

功能?还是iOS 9+中的错误?

(我简直不敢相信Apple提供并建议使用无法从HTML字符串内加载任何本地Web内容的Web视图?!)

如果不看您的实际项目,就很难给出百分百的肯定建议。

然而:

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

我几乎可以肯定,在验证了这两个假设之后,您将使该方法起作用。

我今天遇到了这个问题,我找到了解决方法,可能是原因:

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本身的位置,那么这也将隐式允许根据需要访问子文件夹。对我而言,此问题仅在物理设备上才明显,在模拟器中运行时似乎没有影响,这可能是模拟器和物理设备上的权限工作方式之间的另一个差异。

就个人而言,我不得不切换到使用XWebView,因为WKWebView的开箱即用的行为不允许加载本地文件。XWebView通过在后台加载本地Web服务器并通过它引导本地流量来欺骗它。(XWebView基于WKWebView的顶部)

似乎有点矫kill过正,但这就是我最终要做的事情。

我也一直在尝试类似的限制条件,而且问题似乎在于,除非baseURL引用了应用程序捆绑包,否则无法解析路径例如,如果您在应用程序的文档中包含某些内容,则此操作不起作用。

编辑:我已经为此雷达提交了雷达:// 29130863

好吧,您应该能够将WKWebViews与本地图像和CSS文件(以及与此相关的JavaScript文件)一起使用,并具有已经发现的功能。我的猜测是问题出在您的baseURL变量上。

更新7.5.2017:

我已经完全从另一个我的SO答案更新了代码,该代码以前曾在这里链接到我的答案。我有一个工作项目loadHTMLString().loadFileURL()

尝试baseURL使用以下方法创建

let baseURL = URL(fileURLWithPath: "#path#")

代替:

let baseURL = URL(string: "#path#")

主要区别在于第一种方法file://在路径之前添加前缀。

您可以对图像进行base64编码...我知道这是可行的。虽然不确定是否适合您的用例。

有点好笑,我在做相反的事情时遇到了这个问题-从base64编码到图像文件。

我知道这已经很老了,但是我遇到了完全相同的问题,这花了我数小时的尝试,甚至还发现了这个具有相同问题的线程(Xamarin Forms App)

我的问题是:将远程HTML内容解析为字符串,还添加本地保存的图像(也动态下载,没有应用程序资源)。在模拟器上,所有工具都运行良好,但是在手动设备上,本地图像未显示(也没有显示?或任何表示错误的内容,只是空白帧)。Xamarin Web视图还提供了“ 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;
    }
}

我能够重现类似的问题。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)

问题实际上出在服务器上。服务器应用程序是:

  • 将图像src从更改"http://IP-or-domain/uploads/file.jpg""../../uploads/file.jpg"

- 要么 -

  • 图像src是"http://localhost/uploads/file.jpg" "http://127.0.0.1/uploads/file.jpg" 代替 "http://YOUR-SERVER-IP-ADDRESS/uploads/file.jpg"

在这些情况下,实际设备将无法找到图像。这仅适用于iOS Simulator,因为虚拟设备与服务器和开发机相同。它可以阅读LOCALHOST127.0.0.1

在我的服务器上,我使用的是RTF编辑器(TinyMCE),它在检测到IP地址相同的源之后会自动删除该IP地址。

当我使用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)

这对我有用。

本文地址:http://ios.askforanswer.com/wkwebviewwufashiyongloadhtmlstring_baseurl-jiazaituxianghecss.html
文章标签: ,   ,   ,   ,  
版权声明:本文为原创文章,版权归 admin 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!