我有一个自定义的http组件,它使用Wininet来处理http POST和GET。它工作正常,但有些网站在响应标头中返回Set-Cookie
参数,他们希望浏览器在下次调用时使用此cookie。据我所知,我的基于wininet的组件不处理这些cookie。当我使用像Http Analyzer这样的http嗅探器时,我可以看到它。 IE工作正常。我的请求标题中没有任何不同,它与IE创建的相同。
我应该自己照顾这些饼干吗?如果是这样,怎么样?
答案 0 :(得分:1)
WinInet不处理cookie。你需要自己处理它。
在WinInet图书馆中,您会找到InternetGetCookie()
和InternetSetCookie()
。在Managing Cookies上有一篇很好的MSDN文章。
细节将取决于您的应用程序及其架构,但我通常会发现使用InternetGetCookie()
clunky的实现。相反,我会在调用InternetReadFile()
的情况下检索所有HTTP标头,然后在存在Cookie时调用InternetSetCookie()
:
// Create a session cookie.
bReturn = InternetSetCookie(TEXT("http://www.adventure_works.com"), NULL,
TEXT("TestData = Test"));
可以找到包含检索HTTP标头示例的MSDN文章here。
答案 1 :(得分:0)
上面的答案是错误的。 CInternetSession确实处理cookie。如果此会话下有http响应 返回一个Set-Cookie头,其中的cookie将自动由会话对象保存并返回 在后续请求中到服务器。无需使用SetCookie()。
但是有一些警告和陷阱:没有过期日期返回的Cookie是会话cookie 并且只保存在MEMORY中。当CInternetSession对象被销毁时,它们永远消失。
可以使用SetOption和禁用cookie的请求在CInternetSession对象中设置标志。 请参阅标志INTERNET_OPTION_SUPPRESS_SERVER_AUTH和INTERNET_FLAG_NO_COOKIES。小心,所以你没有这样做。
谨防CACHING。获取一次脚本以获取cookie,然后再次获取它以打印返回的cookie。 它不起作用!没有打印cookie。为什么?因为“文件”是缓存的。在第二次通话时,wininet没有 联系服务器,它再次给你旧的响应,当然没有打印任何cookie。避免 这个你必须使用标志INTERNET_FLAG_RELOAD。这就是本质:
int flags = INTERNET_FLAG_RELOAD;
int port = INTERNET_DEFAULT_HTTP_PORT;
CHttpConnection *connection = session.GetHttpConnection("www.example.com", flags, port);
CHttpFile *fil = connection->OpenRequest(CHttpConnection::HTTP_VERB_GET, "cgi-bin/test.pl",
0,1,0, "HTTP/1.1", flags);
fil->SendRequest();
另请注意,如果Cookie由URL为http://example.com/cgi-bin/test.pl的脚本设置,则它与URL http://example.com/cgi-bin/关联将返回脚本http://example.com/cgi-bin/hello.pl。但是,cookie标头可以改变这种行为。