我要下载文件(CSV)。它位于网站的登录屏幕后面。我想显示WKWebView
以允许用户登录,然后让应用程序在登录后下载文件。
我已尝试在用户登录网站后在WKWebView
之外下载文件,但会话数据似乎是沙箱,因为它下载的是带有登录表单的html文档而不是想要的文件。
我还尝试在WKUserScript
对象中添加WKUserContentController
,但在加载非HTML文件时脚本无法运行。
我是否有办法访问此文件,同时允许用户通过WKWebView
登录?
答案 0 :(得分:93)
目前,WKWebView实例将忽略任何默认网络存储(NSURLCache,NSHTTPCookieStorage,NSCredentialStorage)以及可用于自定义网络请求的标准网络类(NSURLProtocol等)。
因此,WKWebView实例的cookie不存储在应用程序的标准Cookie存储中,因此仅使用标准Cookie存储的NSURLSession / NSURLConnection无法访问WKWebView的cookie(这可能就是问题所在你有:“登录状态”很可能存储在cookie中,但NSURLSession / NSURLConnection将不会看到cookie)。
缓存,凭证等也是如此.WKWebView有自己的私有存储,因此不能很好地使用标准的Cocoa网络类。
您也无法自定义请求(添加自己的自定义HTTP标头,修改现有标头等),使用您自己的自定义URL方案等,因为WKWebView也不支持NSURLProtocol。
所以现在WKWebView对许多应用程序来说都没用,因为它不参与Cocoa的标准网络API。
我仍然希望Apple会在iOS 8发布之前对其进行更改,因为否则WKWebView对于许多应用程序来说都是无用的,而且我们可能会更长时间地使用UIWebView。
因此,向Apple发送错误报告,以便Apple了解这些问题是严重的,需要修复。
答案 1 :(得分:15)
您是否检查过请求中的响应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);
}
答案 2 :(得分:1)
我已经完成了类似于您尝试做的事情:
navigationDelegate
-webView:decidePolicyForNavigationResponse:decisionHandler
navigationResponse.response
(将其强制转换为NSHTTPURLResponse*
)并查找包含会话信息的Set-Cookie
标头您需要经过身份验证的会话。 Cookie
标头来下载CSV。 请注意,委托方法仅用于"主框架"要求。这意味着AJAX请求或内部框架不会触发它。整个页面必须刷新才能工作。
如果您需要触发AJAX请求,iframe等行为,您需要注入一些javascript。
答案 3 :(得分:1)
您可以获取Cookie via Javascript:
然后,您可以使用获取的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()
})
答案 4 :(得分:0)
当我尝试来自userContentController didReceiveScriptMessage的请求时,我似乎没有会话cookie。
但是,当从decisionPolicyForNavigationAction调用时,以下代码检测到我已登录。
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()