关于ios:WKWebView从间接链接下载zip文件

WKWebView download zip file from an indirect link

我正在尝试从iOS中的WKWebView捕获zip文件的下载。登录后,转到此链接,请求存档,然后单击"下载"按钮,则不会下载该zip文件。但是,WKWebView确实会在网络浏览器中显示该文件,或者看起来会这样做(请参见下面的屏幕截图)。当尝试从Web视图下载文件时,我仅提取HTML文件。

Download Button Shows Up
Zip File displayed in WKWebView

有人可以在此处提供有关捕获和下载zip文件的正确方法的一些指导吗?注意,该zip文件没有直接链接。 WKWebView委托方法的代码,以及下面的下载处理程序。

webView didFinishNavigation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
 - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
    NSURLComponents *comps = [[NSURLComponents alloc] initWithURL:webView.URL

                                          resolvingAgainstBaseURL:NO];
    comps.query = nil;

    NSLog(@"did finish nav URL: %@", webView.URL);

    if ([webView.URL.absoluteString isEqualToString:LI_DOWNLOAD_URL]) {

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
            [DownloadHandler downloadFileFromURL:webView.URL completion:^(NSString *filepath) {
                NSLog(@"%@",filepath);

            }];
        });
    }
    else if ([comps.string  isEqual: LI_REDIRECT_CATCH1] ||
        [comps.string  isEqual: LI_REDIRECT_CATCH2] ||
        [comps.string  isEqual: LI_REDIRECT_CATCH3]) {

        self.statusText.text = @"Tap the \"Sign In\" button to log into LinkedIn";
    }
    else if ([comps.string isEqual: LI_EXPORT_PAGE]) {
        NSString *javascript = @"javascript:" \\
                               "var reqBtn = document.getElementById('request-button');" \\
                               "var pndBtn = document.getElementById('pending-button');" \\
                               "var dwnBtn = document.getElementById('download-button');" \\
                               "if (reqBtn) {" \\
                               "   window.scrollTo(reqBtn.offsetLeft, 0);" \\
                               "   window.webkit.messageHandlers.dataExport.postMessage('willRequestData');" \\
                               "   reqBtn.addEventListener('click', function() {" \\
                               "       window.webkit.messageHandlers.dataExport.postMessage('didRequestData');" \\
                               "   }, false);" \\
                               "} else if (pndBtn) {" \\
                               "   window.scrollTo(pndBtn.offsetLeft, 0);" \\
                               "   window.webkit.messageHandlers.dataExport.postMessage('isRequestPending');" \\
                               "} else if (dwnBtn) {" \\
                               "   window.scrollTo(dwnBtn.offsetLeft, 0);" \\
                               "   window.webkit.messageHandlers.dataExport.postMessage('willDownloadData');" \\
                               "   dwnBtn.onclick = function() {" \\
                               "       window.webkit.messageHandlers.dataExport.postMessage('didDownloadData');" \\
                               "   };" \\
                               "}";

        [self.webView evaluateJavaScript:javascript completionHandler:nil];
    }
}

下载处理程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
+ (void)downloadFileFromURL:(NSURL *)url completion:(void (^)(NSString *filepath))completion {

    NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];

    NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration];

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    request.HTTPMethod = @"POST";

    NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request
                                                    completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

            if (!error) {

                dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{

                    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
                    NSString *documentsDirectory = [paths objectAtIndex:0];
                    NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:@"linkedin-file-export.zip"];

                    [data writeToFile:dataPath atomically:YES];

                    completion(dataPath);
                });
            }
            else {
                NSLog(@"%@",error);

                completion([NSString string]);
            }
    }];
    [postDataTask resume];
}

我也通过使用UIWebView进行了尝试,并且得到了相同的结果。在Android中,这可以通过下载侦听器来完成。我愿意采用这种方法(如果有的话),但我认为它不适用于iOS。

谢谢你的帮助。


您正在尝试在webview完成加载zip文件url之后下载zip。我认为方法应该是阻止webview加载zip文件url,并允许您的API将文件下载到所需的路径。

如下所示。 以下代码段假设zip文件的网址具有扩展名.zip

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {

    NSURLRequest *request = navigationAction.request;
    NSString *fileExtension = [[request URL]absoluteString].pathExtension;
    if(fileExtension.length && [fileExtension caseInsensitiveCompare:@"zip"] == NSOrderedSame){
        //Do not load the zip url in the webview.
        decisionHandler(WKNavigationActionPolicyCancel);
        //Instead use the API to download the file
        [DownloadHandler downloadFileFromURL:[request URL] completion:^(NSString *filepath) {
            NSLog(@"%@",filepath);

        }];
    }

    //Allow all other request types to load in the webview
    decisionHandler(WKNavigationActionPolicyAllow);
}

很想知道这是否对您有用。