如何删除 WKWebview cookie
Posted
技术标签:
【中文标题】如何删除 WKWebview cookie【英文标题】:How to delete WKWebview cookies 【发布时间】:2015-09-26 04:43:02 【问题描述】:目前我正在这样做
NSHTTPCookie *cookie;
NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (cookie in [storage cookies])
[storage deleteCookie:cookie];
但它不适用于 ios 8、64 位设备。
WKWebview 的干净 cookie 还有其他方法吗?任何帮助将不胜感激。谢谢。
【问题讨论】:
【参考方案1】:Apple 为 iOS 9 发布了新的 API,因此现在我们可以使用以下代码删除为 WKWebView 存储的特定于域的 cookie,但这会仅适用于具有 iOS 版本 9的设备或 稍后:
WKWebsiteDataStore *dateStore = [WKWebsiteDataStore defaultDataStore];
[dateStore
fetchDataRecordsOfTypes:[WKWebsiteDataStore allWebsiteDataTypes]
completionHandler:^(NSArray<WKWebsiteDataRecord *> * __nonnull records)
for (WKWebsiteDataRecord *record in records)
if ( [record.displayName containsString:@"facebook"])
[[WKWebsiteDataStore defaultDataStore]
removeDataOfTypes:record.dataTypes
forDataRecords:@[record]
completionHandler:^
NSLog(@"Cookies for %@ deleted successfully",record.displayName);
];
];
sn-p 以上肯定适用于 iOS 9 及更高版本。不幸的是,如果我们在 iOS 9 之前的 iOS 版本中使用 WKWebView,我们仍然必须坚持传统的方法并删除整个cookies存储如下。
NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *cookiesFolderPath = [libraryPath stringByAppendingString:@"/Cookies"];
NSError *errors;
[[NSFileManager defaultManager] removeItemAtPath:cookiesFolderPath error:&errors];
以下是 Swift 3 版本
let dataStore = WKWebsiteDataStore.default()
dataStore.fetchDataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes()) (records) in
for record in records
if record.displayName.contains("facebook")
dataStore.removeData(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes(), for: [record], completionHandler:
print("Deleted: " + record.displayName);
)
还有 Swift 4:
let dataStore = WKWebsiteDataStore.default()
dataStore.fetchDataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes()) records in
dataStore.removeData(
ofTypes: WKWebsiteDataStore.allWebsiteDataTypes(),
for: records.filter $0.displayName.contains("facebook") ,
completionHandler: completion
)
【讨论】:
使用这种方法只返回域级别,即 facebook.com ,它告诉我里面有 cookie。但我无法删除或检索单个项目。例如 facebook 内的会话 cookie。旧方法会将所有 cookie 扁平化为一个列表。这是设计使然还是我错过了什么。我找不到任何信息。 - @pankaj 您是否尝试过删除 WKWebsiteDataTypeSessionStorage 类型的记录? 遗憾的是,它被用作 cookie,在 safari 中的调试显示我有两个域被存储,还有一些其他项目正在使用 cookie、本地存储等。在 HTTPCookieStore 下,您会看到所有域的平面列表cookie 列表。我想要的这个会话 cookie 就在里面。但不是在通过新的 DataStore 请求时。但是,我确实看到了两个域项目。因此,我需要深入了解第二个级别。 @PankajGaikar 有没有办法从域中删除特定的 cookie? 请注意,WebKit API 必须在主线程上调用,这与 NSHTTPCookieStorage 不同。如果您在后台线程中清除 cookie,则需要坚持使用 NSHTTPCookieStorage。【参考方案2】:Swift 3 版本的 Sarat 的回答:
let dataStore = WKWebsiteDataStore.default()
dataStore.fetchDataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes()) (records) in
for record in records
if record.displayName.contains("facebook")
dataStore.removeData(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes(), for: [record], completionHandler:
print("Deleted: " + record.displayName);
)
【讨论】:
【参考方案3】:支持 iOS 11.0 及以上版本
以下解决方案对我很有效:
步骤 1. 从 HTTPCookieStorage
中删除 Cookie
第二步,从WKWebsiteDataStore
获取数据记录并删除。
第 3 步。创建一个新的WKProcessPool
创建一个 WKWebView 扩展:
extension WKWebView
func cleanAllCookies()
HTTPCookieStorage.shared.removeCookies(since: Date.distantPast)
print("All cookies deleted")
WKWebsiteDataStore.default().fetchDataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes()) records in
records.forEach record in
WKWebsiteDataStore.default().removeData(ofTypes: record.dataTypes, for: [record], completionHandler: )
print("Cookie ::: \(record) deleted")
func refreshCookies()
self.configuration.processPool = WKProcessPool()
用法:
override func viewWillAppear(_ animated: Bool)
super.viewWillAppear(true)
webView.cleanAllCookies()
webView.refreshCookies()
【讨论】:
【参考方案4】:这些选项都不适合我,但我找到了一个:
let config = WKWebViewConfiguration()
if #available(iOS 9.0, *)
config.websiteDataStore = WKWebsiteDataStore.nonPersistentDataStore()
else
// I have no idea what to do for iOS 8 yet but this works in 9.
let webView = WKWebView(frame: .zero, configuration: config)
【讨论】:
使用此存储,您正在使用“私有模式”,其中 localStorage 和其他将不可用,因此您的 javascript 可能会失败,但是是的,它会擦除所有内容【参考方案5】:在 iOS9 中:
//// Optional data
NSSet *websiteDataTypes
= [NSSet setWithArray:@[
WKWebsiteDataTypeDiskCache,
//WKWebsiteDataTypeOfflineWebApplicationCache,
WKWebsiteDataTypeMemoryCache,
//WKWebsiteDataTypeLocalStorage,
//WKWebsiteDataTypeCookies,
//WKWebsiteDataTypeSessionStorage,
//WKWebsiteDataTypeIndexedDBDatabases,
//WKWebsiteDataTypeWebSQLDatabases
]];
//// All kinds of data
//NSSet *websiteDataTypes = [WKWebsiteDataStore allWebsiteDataTypes];
//// Date from
NSDate *dateFrom = [NSDate dateWithTimeIntervalSince1970:0];
//// Execute
[[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:websiteDataTypes modifiedSince:dateFrom completionHandler:^
// Done
NSLog(@"remove done");
];
【讨论】:
【参考方案6】:除了清除共享cookie存储中的cookie之外,我会尝试清除缓存(NSURLCache)并丢弃WKWebView并使用新的WKProcessPool创建一个新的
【讨论】:
好吧,我很害怕,但这也不起作用。我在某处读到我也必须从设备中删除本地库,我也会尝试这样做。 如果你使用 WKProcessPool 技巧(来自***.com/questions/33156567/…)在多个 WKWebViews 之间共享 cookie,你需要像答案一样创建一个新的 WKProcessPool。【参考方案7】:Swift 4 和更短的版本:
let dataStore = WKWebsiteDataStore.default()
dataStore.fetchDataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes()) records in
dataStore.removeData(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes(),
for: records.filter $0.displayName.contains("facebook") ,
completionHandler: completion)
【讨论】:
【参考方案8】:在所有现有答案的基础上,如果您尝试清除特定 WKWebView 实例“webView”的 cookie 和数据记录,而不是“默认”存储的 cookie 和数据记录,则可以使用以下内容:
let dataStore = webView.configuration.websiteDataStore
let cookieStore = dataStore.httpCookieStore
cookieStore.getAllCookies
$0.forEach cookie in
cookieStore.delete(cookie)
dataStore.fetchDataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes()) records in
records.forEach record in
dataStore.removeData(ofTypes: record.dataTypes, for: [record])
【讨论】:
【参考方案9】:现在 iOS 8.2 中似乎正在使用 NSHTTPCookieStorage 来根据需要正确清除 cookie。在打开基于 WKWebView 的登录之前,我已经发布了一个可以运行此代码的应用程序:
NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (NSHTTPCookie *cookie in [storage cookies])
[storage deleteCookie:cookie];
在 iOS 8.2 之前,网站会使用保存的 cookie 自动登录,现在它会正确要求用户重新登录。这一切都是在我没有向应用程序发送更新的情况下发生的。 :)
【讨论】:
这没什么意义,你的代码和我的代码是一样的,虽然我也试过这个代码。不,这对我也不起作用。 好的没问题我等你的回答 现在,我一无所知,不知道这里发生了什么,仍然会尝试一些解决方法..【参考方案10】:Esqarrouth 的回答只是部分正确。 正确的 swift 版本是:
var libraryPath : String = NSFileManager().URLsForDirectory(.LibraryDirectory, inDomains: .UserDomainMask).first!.path!
libraryPath += "/Cookies"
do
try NSFileManager.defaultManager().removeItemAtPath(libraryPath)
catch
print("error")
NSURLCache.sharedURLCache().removeAllCachedResponses()
【讨论】:
【参考方案11】:WKWebview 在 [NSHTTPCookieStorage sharedHTTPCookieStorage] 中不存储任何内容。
清除 WKWebsiteDataStore 将是解决此问题的方法。
对于使用WKwebview的IOS8,此方法不适用..
【讨论】:
【参考方案12】:在 WKWebView 中,写入和读取需要一些时间,因此当您获取 cookie 时,您将获得更新的 cookie,但有时它会是旧的,并且您将在任何服务器请求上收到错误。我在 3 天内遇到了这个问题,
解决方案:无需在 WKWebsiteDataStore 中存储 cookie。
获取 cookie:
斯威夫特:
extension WKWebView
private var httpCookieStore: WKHTTPCookieStore return WKWebsiteDataStore.default().httpCookieStore
func getCookies(for domain: String? = nil, completion: @escaping ([String : Any])->())
var cookieDict = [String : AnyObject]()
httpCookieStore.getAllCookies cookies in
for cookie in cookies
if let domain = domain
if cookie.domain.contains(domain)
cookieDict[cookie.name] = cookie.properties as AnyObject?
else
cookieDict[cookie.name] = cookie.properties as AnyObject?
completion(cookieDict)
目标-c:
-(void )getAllCookies
NSMutableString *updatedCockies= [[NSMutableString alloc] init];
if (@available(iOS 11.0, *))
WKHTTPCookieStore *cookieStore = _webView.configuration.websiteDataStore.httpCookieStore;
NSLog(@"cookieStore *********************: %@",cookieStore);
[cookieStore getAllCookies:^(NSArray* cookies)
NSHTTPCookie *cookie;
for(cookie in cookies)
NSLog(@"%@",cookie)
self->updatedCookie = updatedCockies;
NSLog(@"cookie *********************: %@", self->updatedCookie);
];
每次你想要新的cookie,所以你需要写下面的代码: 鉴于夏皮奥
斯威夫特:
let config = WKWebViewConfiguration()
if #available(iOS 9.0, *)
config.websiteDataStore = WKWebsiteDataStore.nonPersistentDataStore()
else
// I have no idea what to do for iOS 8 yet but this works in 9.
let webView = WKWebView(frame: .zero, configuration: config)
目标 C--
WKWebViewConfiguration *wkWebConfig = [WKWebViewConfiguration new];
wkWebConfig.websiteDataStore = [WKWebsiteDataStore nonPersistentDataStore];
self.webView = [[WKWebView alloc] initWithFrame: CGRectZero
configuration: wkWebConfig];
********每次你都会得到新的cookies********
【讨论】:
【参考方案13】:斯威夫特 5
/// old API cookies
for cookie in HTTPCookieStorage.shared.cookies ?? []
HTTPCookieStorage.shared.deleteCookie(cookie)
/// URL cache
URLCache.shared.removeAllCachedResponses()
/// WebKit cache
let date = Date(timeIntervalSince1970: 0)
WKWebsiteDataStore.default().removeData(
ofTypes: WKWebsiteDataStore.allWebsiteDataTypes(),
modifiedSince: date,
completionHandler:)
【讨论】:
【参考方案14】:Swift 版本:
var libraryPath = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.LibraryDirectory, NSSearchPathDomainMask.UserDomainMask, false).first!
libraryPath += "/Cookies"
do
let result = try NSFileManager.defaultManager().removeItemAtPath(libraryPath)
print(result)
catch
print("error")
NSURLCache.sharedURLCache().removeAllCachedResponses()
【讨论】:
这总是对我返回一个错误。我为NSSearchPathForDirectoriesInDomains
中的最后一个参数传递了true
,它可以工作以上是关于如何删除 WKWebview cookie的主要内容,如果未能解决你的问题,请参考以下文章
Swift 4 WKWebView cookie 获取和删除同步问题
更改 WKWebview 框架高度后如何删除 WKScrollView 内的空白区域?
如何从 WKWebview 中删除或隐藏 PDF 的页面计数器?