如何截获WKWebView请求以检测哪些本地资源文件(css,js,png,...)与HTML文件一起加载? [英] How to intercept a WKWebView request to detect which local resource files (css, js, png, ...) load together with a HTML file?

查看:338
本文介绍了如何截获WKWebView请求以检测哪些本地资源文件(css,js,png,...)与HTML文件一起加载?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个HTML文件,该文件的内容中包含本地资源文件,例如css,js和png文件.这些本地资源文件为zip格式.我的应用程序使用WKWebView来显示此html文件.我想找到一种解决方案来拦截Web视图请求,以检测哪些本地资源文件与此html文件一起加载->然后,如果它们仍为zip格式,则将其解压缩.

I have a HTML file which contains local resource files such as css, js and png files inside its content. These local resource files are in zip format. My app use WKWebView to display this html file. I want to find a solution to intercept the web view request to detect which local resource files are load together with this html file -> then unzip them if they are still zip format.

我的HTML数据内容包含数千个这些本地资源文件,因此在显示内容之前,我无法将它们全部解压缩.借助UIWebView,我们使用NSURLProtocol子类来拦截请求,检测本地资源文件并根据用户正在查看的html页面按需将其解压缩.

My HTML data content contains thousands of these local resource file so I can't unzip all of them before display content. With UIWebView, we are using NSURLProtocol subclass to intercept the request, detect local resource files and un-zip it on demand based on the html page which user is viewing.

将UIWebView转换为WKWebView时遇到此问题.在此处发布了类似的问题: https://forums.developer.apple.com/thread/87474

I am having this issue when convert UIWebView to WKWebView. Similar problem was post here: https://forums.developer.apple.com/thread/87474

========更新=======>

======= Update =======>

我通过使用 WKURLSchemeHandler 弄清楚了.

注意:您需要将文件方案更改为自定义方案,才能使用WKURLSchemeHandler,因为它不适用于标准方案,例如文件,http,https.

1.向WKWebView注册自定义方案

    let configuration = WKWebViewConfiguration()
    configuration.setURLSchemeHandler(self, forURLScheme: "x-file")
    webView = WKWebView(frame: view.bounds, configuration: configuration)

2.将文件方案转换为自定义方案(x文件),然后使用WKWebView加载

    let htmlPath = Bundle.main.path(forResource: "index", ofType: "html")
    var htmlURL = URL(fileURLWithPath: htmlPath!, isDirectory: false)                    
    htmlURL = self.changeURLScheme(newScheme: "x-file", forURL: htmlURL)
    self.webView.load(URLRequest(url: htmlURL))


3.实现WKURLSchemeHandler协议的2种方法,并处理WKURLSchemeTask的3种委托方法.

    func webView(_ webView: WKWebView, start urlSchemeTask: WKURLSchemeTask) {
        print("Function: \(#function), line: \(#line)")
        print("==> \(urlSchemeTask.request.url?.absoluteString ?? "")\n")

        // Your local resource files will be catch here. You can determine it by checking the urlSchemeTask.request.url.
        // From here I will unzip local resource files (js, css, png,...) if they are still in zip format
        ....

        // Handle WKURLSchemeTask delegate methods
        let url = changeURLScheme(newScheme: "file", forURL: urlSchemeTask.request.url!)

        do {
            let data = try Data(contentsOf: url)

            urlSchemeTask.didReceive(URLResponse(url: urlSchemeTask.request.url!, mimeType: "text/html", expectedContentLength: data.count, textEncodingName: nil))
            urlSchemeTask.didReceive(data)
            urlSchemeTask.didFinish()
        } catch {
            print("Unexpected error when get data from URL: \(url)")
        }
    }

    func webView(_ webView: WKWebView, stop urlSchemeTask: WKURLSchemeTask) {
        print("Function: \(#function), line: \(#line)")
        print("==> \(urlSchemeTask.request.url?.absoluteString ?? "")\n")
    }

推荐答案

如果WKWebView加载了本地html文件,您可以只授予WKWebView访问本地应用程序资源的权限,如下所示:

If WKWebView loads a local html file you could just give the WKWebView access to local app resources like so:

NSURL *documentDirectoryURL = [NSURL fileURLWithPath:DOCUMENTS_DIRECTORY];

// This code gives acces to a file that is outside of our webview html file root directory
[self.webView loadFileURL:documentDirectoryURL allowingReadAccessToURL:documentDirectoryURL];

// If you use one of these loads after, they will too have access if they are in app html files
[self.webView loadRequest:<inAppHTMLFile>];
[self.webView loadHTMLString: baseURL:];

这里可以访问文档目录中的所有文件.

This here gives access to all files in the document directory.

当我想将本地资源链接到在线页面时,我发现您的解决方案很有帮助.

I found your solution helpful when I wanted to link local resources to online pages.

WKUserContentController *contentController = [[WKUserContentController alloc]init];
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc]init];
CustomFileShemeHandler *schemeHandler = [[CustomFileShemeHandler alloc] init];
[config setURLSchemeHandler:schemeHandler forURLScheme:@"myApp-images"];
config.userContentController = contentController;
self.webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:config];



//CustomFileShemeHandler.m

@implementation CustomFileShemeHandler

- (void)webView:(nonnull WKWebView *)webView startURLSchemeTask:(nonnull id<WKURLSchemeTask>)urlSchemeTask {
    NSURL *customFileURL = urlSchemeTask.request.URL;
    NSString *securityFilter = [NSString stringWithFormat:@"Documents/LocalAppImages"];

    if (![customFileURL.absoluteString containsString:securityFilter]) {
        return;
    }

    NSURL *fileURL = [self changeURLScheme:customFileURL toScheme:@"file"];
    NSURLRequest* fileUrlRequest = [[NSURLRequest alloc] initWithURL:fileURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:.1];

    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:fileUrlRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        NSURLResponse *response2 = [[NSURLResponse alloc] initWithURL:urlSchemeTask.request.URL MIMEType:response.MIMEType expectedContentLength:data.length textEncodingName:nil];
        if(error){
            [urlSchemeTask didFailWithError:error];
        }
        [urlSchemeTask didReceiveResponse:response2];
        [urlSchemeTask didReceiveData:data];
        [urlSchemeTask didFinish];
    }];

    [dataTask resume];
}

- (void)webView:(nonnull WKWebView *)webView stopURLSchemeTask:(nonnull id<WKURLSchemeTask>)urlSchemeTask {
    NSLog(@"DUNNO WHAT TO DO HERE");
}

- (NSURL *)changeURLScheme:(NSURL *)url toScheme:(NSString *)newScheme {
    NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:YES];
    components.scheme = newScheme;
    return components.URL;
}

在webView中打开的任何页面都可以使用其完整路径和自定义方案链接到本地​​资源:

With this any page open in the webView can link to a local resource using its full path an the custom scheme:

<img src="myApp-images:///<YourDocumentsAppPahtHere>/LocalAppImages/funnyDog.jpg">

这篇关于如何截获WKWebView请求以检测哪些本地资源文件(css,js,png,...)与HTML文件一起加载?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆