ios 是否可以使用 sharedHTTPCookieStorage 为 UIWebView 手动设置 cookie?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5954382/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is it possible to set a cookie manually using sharedHTTPCookieStorage for a UIWebView?
提问by Mauvis Ledford
I have webviews inside of an iOS application that require an authentication cookie to be properly authenticated. I'm looking for a way to set a cookie inside of an iOS application's webview without having to make an outbound request to set the cookie as I have auth information on the client already.
我在 iOS 应用程序中有 webviews,需要正确验证身份验证 cookie。我正在寻找一种在 iOS 应用程序的 web 视图中设置 cookie 的方法,而不必发出出站请求来设置 cookie,因为我已经在客户端上有了身份验证信息。
This postshows us where the UIWebView cookies are stored.
这篇文章向我们展示了 UIWebView cookie 的存储位置。
Right now I'm loading a hidden web view to make an outbound request but would prefer not to have to make an external request for setting a simple cookie.
现在我正在加载一个隐藏的 web 视图来发出一个出站请求,但我宁愿不必为设置一个简单的 cookie 发出一个外部请求。
回答by kball
Yes, you can do this. First, in applicationDidBecomeActive add this line
是的,你可以这样做。首先,在 applicationDidBecomeActive 添加这一行
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways];
The cookieAcceptPolicy is shared across apps and can be changed without your knowledge, so you want to be sure you have the accept policy you need every time your app is running.
cookieAcceptPolicy 在应用程序之间共享,并且可以在您不知情的情况下更改,因此您要确保每次应用程序运行时都拥有所需的接受策略。
Then, to set the cookie:
然后,设置cookie:
NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];
[cookieProperties setObject:@"testCookie" forKey:NSHTTPCookieName];
[cookieProperties setObject:@"someValue123456" forKey:NSHTTPCookieValue];
[cookieProperties setObject:@"www.example.com" forKey:NSHTTPCookieDomain];
[cookieProperties setObject:@"www.example.com" forKey:NSHTTPCookieOriginURL];
[cookieProperties setObject:@"/" forKey:NSHTTPCookiePath];
[cookieProperties setObject:@"0" forKey:NSHTTPCookieVersion];
// set expiration to one month from now or any NSDate of your choosing
// this makes the cookie sessionless and it will persist across web sessions and app launches
/// if you want the cookie to be destroyed when your app exits, don't set this
[cookieProperties setObject:[[NSDate date] dateByAddingTimeInterval:2629743] forKey:NSHTTPCookieExpires];
NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
This cookie has the name testCookie and value someValue123456 and will be sent with any http request to www.example.com.
此 cookie 的名称为 testCookie,值为 someValue123456,将与任何 http 请求一起发送到 www.example.com。
For one big caveat to setting cookies, please see my question here!
对于设置 cookie 的一个重要警告,请在此处查看我的问题!
NSHTTPCookieStorage state not saved on app exit. Any definitive knowledge/documentation out there?
回答by more tension
Edit: adapting for edited question
编辑:适应编辑的问题
NSHTTPCookieStorage
has a -setCookies:forURL:mainDocumentURL:
method, so the easy thing to do is use NSURLConnection
and implement -connection:didReceiveResponse:
, extracting cookies and stuffing them into the cookie jar:
NSHTTPCookieStorage
有一个-setCookies:forURL:mainDocumentURL:
方法,所以简单的事情就是使用NSURLConnection
和实现-connection:didReceiveResponse:
,提取cookie并将它们塞进cookie jar:
- ( void )connection: (NSURLConnection *)connection
didReceiveResponse: (NSURLResponse *)response
{
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
NSArray *cookies;
cookies = [ NSHTTPCookie cookiesWithResponseHeaderFields:
[ httpResponse allHeaderFields ]];
[[ NSHTTPCookieStorage sharedHTTPCookieStorage ]
setCookies: cookies forURL: self.url mainDocumentURL: nil ];
}
(You can also simply extract an NSDictionary
object from the NSHTTPCookie
with properties
, and then write the dictionary to the disk. Reading it back in is as easy as using NSDictionary
's -dictionaryWithContentsOfFile:
and then creating the cookie with -initWithProperties:
.)
(您也可以简单地NSDictionary
从NSHTTPCookie
with 中提取一个对象properties
,然后将字典写入磁盘。读回它就像使用NSDictionary
's-dictionaryWithContentsOfFile:
然后用 来创建 cookie一样简单-initWithProperties:
。)
Then you can pull the cookie back out of the storage when you need it:
然后,您可以在需要时将 cookie 从存储中取出:
- ( void )reloadWebview: (id)sender
{
NSArray *cookies;
NSDictionary *cookieHeaders;
NSMutableURLRequest *request;
cookies = [[ NSHTTPCookieStorage sharedHTTPCookieStorage ]
cookiesForURL: self.url ];
if ( !cookies ) {
/* kick off new NSURLConnection to retrieve new auth cookie */
return;
}
cookieHeaders = [ NSHTTPCookie requestHeaderFieldsWithCookies: cookies ];
request = [[ NSMutableURLRequest alloc ] initWithURL: self.url ];
[ request setValue: [ cookieHeaders objectForKey: @"Cookie" ]
forHTTPHeaderField: @"Cookie" ];
[ self.webView loadRequest: request ];
[ request release ];
}
回答by JAL
In Swift 3 all of the keys are wrapped in the HTTPCookiePropertyKey
struct:
在 Swift 3 中,所有键都包含在HTTPCookiePropertyKey
结构中:
let cookieProperties: [HTTPCookiePropertyKey : Any] = [.name : "name",
.value : "value",
.domain : "www.example.com",
.originURL : "www.example.com",
.path : "/",
.version : "0",
.expires : Date().addingTimeInterval(2629743)
]
if let cookie = HTTPCookie(properties: cookieProperties) {
HTTPCookieStorage.shared.setCookie(cookie)
}
回答by kindaian
There is need to work around the limitations on cookies introduced by iOS 10, which makes them invisible to different processes.
需要解决 iOS 10 引入的 cookie 限制,这使得它们对不同的进程不可见。
This means that on devices with multiprocessing capability, webviews are a distinct process then your app, which means your "app" session is not transmitted automatically to the webview anymore.
这意味着在具有多处理功能的设备上,webviews 是一个与您的应用程序不同的进程,这意味着您的“应用程序”会话不再自动传输到 webview。
So in essense, you will need to do it (even is previous posters where right, it was working automatically before iOS10).
所以从本质上讲,你需要这样做(即使以前的海报是正确的,它在 iOS10 之前自动运行)。