我怎样才能使用WKWebView检索文件?

有一个文件(CSV),我想下载。 它位于网站的login屏幕后面。 我想显示一个WKWebView允许用户login,然后在应用程序login后下载文件。

我已经尝试在用户login到网站后下载WKWebView之外的文件,但会话数据似乎是沙箱,因为它下载与login表单,而不是所需的文件的HTML文档。

我也尝试将WKUserScript添加到WKUserContentController对象,但是在加载非HTML文件时脚本不能运行。

有没有办法让我访问这个文件,同时允许用户通过WKWebViewlogin?

现在,WKWebView实例将忽略任何默认networking存储(NSURLCache,NSHTTPCookieStorage,NSCredentialStorage)以及可用于自定义networking请求的标准networking类(NSURLProtocol等)。

因此,WKWebView实例的Cookie不会存储在您的应用程序的标准Cookie存储中,因此仅使用标准Cookie存储的NSURLSession / NSURLConnection无法访问WKWebView的Cookie(而这恰好可能是您遇到的问题: “login状态”很可能存储在cookie中,但NSURLSession / NSURLConnection不会看到cookie)。

caching,凭证等也是如此.WKWebView拥有自己的私有存储,因此不能很好地与标准的Cocoanetworking类一起使用。

你也不能自定义请求(添加自己的自定义HTTP头,修改现有的头等),使用自己的自定义URLscheme等,因为WKWebView不支持NSURLProtocol。

所以现在WKWebView对许多应用程序来说都是无用的,因为它不参与Cocoa的标准networkingAPI。

我仍然希望Apple能够改变这个状况,直到iOS 8发布,否则WKWebView对于很多应用程序来说都是没用的,我们可能会坚持使用UIWebView。

因此,向苹果发送错误报告,所以苹果得知这些问题是严重的,需要修复。

你有没有检查从请求返回的响应cookie。 你可以使用这样的委托方法。

 - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{ NSHTTPURLResponse *response = (NSHTTPURLResponse *)navigationResponse.response; NSArray *cookies =[NSHTTPCookie cookiesWithResponseHeaderFields:[response allHeaderFields] forURL:response.URL]; for (NSHTTPCookie *cookie in cookies) { [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie]; } decisionHandler(WKNavigationResponsePolicyAllow); } 

我已经完成了类似于你想要做的事情:

  • 使用networking视图login,因为你已经在做
  • 在你的webview上设置一个navigationDelegate
  • 在委托中实现-webView:decidePolicyForNavigationResponse:decisionHandler
  • 当调用委托方法(用户login后)时,可以检查navigationResponse.response (将其转换为NSHTTPURLResponse* ),然后查找包含会话信息的Set-Cookie头,以便validation会话。
  • 您可以通过在响应中指定Cookie来手动指定您的请求中的Cookie标头来下载CSV。

请注意,委托方法仅被称为“主框架”请求。 这意味着AJAX请求或内部框架不会触发它。 整个页面必须刷新才能正常工作。

如果你需要触发AJAX请求的行为,iframes等你需要注入一些JavaScript。

当我尝试来自userContentController didReceiveScriptMessage的请求时,我似乎没有会话cookie。

但是,从DecisionPolicyForNavigationAction调用时,以下代码检测到我已login。

  let urlPath: String = "<api endpoint at url at which you are logged in>" let url = NSURL(string: urlPath) let session = NSURLSession.sharedSession() let task = session.dataTaskWithURL(url!, completionHandler: {data, response, error -> Void in let string1 = NSString(data: data, encoding: NSUTF8StringEncoding) println(string1) println(data) if(error != nil) { println("Error sending token to server") // Print any error to the console println(error.localizedDescription) } var err: NSError? }) task.resume() 

你可以通过Javascript获取cookie:

然后,您可以使用获取的Cookie手动下载文件:

 webView.evaluateJavaScript("(function() { return document.cookie })()", completionHandler: { (response, error) -> Void in let cookie = response as! String let request = NSMutableURLRequest(URL: docURL) request.setValue(cookie, forHTTPHeaderField: "Cookie") NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { (data, response, error) in // Your CSV file will be in the response object }).resume() })