Wininet 是不是处理 HTTP 标头值“Set-Cookie”?

Posted

技术标签:

【中文标题】Wininet 是不是处理 HTTP 标头值“Set-Cookie”?【英文标题】:Does Wininet handle the HTTP header value "Set-Cookie"?Wininet 是否处理 HTTP 标头值“Set-Cookie”? 【发布时间】:2011-07-15 20:24:41 【问题描述】:

我有一个使用 Wininet 处理 http POST 和 GET 的自定义 http 组件。它工作正常,但有些网站在响应标头中返回 Set-Cookie 参数,他们希望浏览器在下次调用时使用此 cookie。据我所知,我的基于 wininet 的组件没有处理这些 cookie。当我使用一些像 Http Analyzer 这样的 http 嗅探器时,我可以看到它。 IE 工作正常。我的请求头没有什么不同,和IE创建的一样。

我应该自己处理这些饼干吗?如果有,怎么做?

【问题讨论】:

【参考方案1】:

WinInet 不处理 cookie。你需要自己处理。

在 WinInet 库中,您会找到 InternetGetCookie()InternetSetCookie()。 Managing Cookies 上有一篇很好的 MSDN 文章。

具体情况取决于您的应用程序及其架构,但我通常会找到使用 InternetGetCookie() 笨重的实现。相反,我将检索与调用 InternetReadFile() 一致的所有 HTTP 标头,然后如果存在 cookie,则调用 InternetSetCookie()

// Create a session cookie.
bReturn = InternetSetCookie(TEXT("http://www.adventure_works.com"), NULL,
            TEXT("TestData = Test"));

可以在here 找到包含检索 HTTP 标头示例的 MSDN 文章。

【讨论】:

我应该如何找到需要设置 cookie 的主机?我的意思是,如果我将数据发布到xxx.com/xxx/xxxx.dll?xxx=xxx,我应该将cookie 设置为主机xxx.com 吗?如果下一个请求是针对相同的 url,但针对的是 https 页面? 是的,cookie 明确保留在返回 set-cookie 标头的域中。尝试阅读 cookie RFC:ietf.org/rfc/rfc2109.txt 好吧,这对我不起作用。 cookie 就像“seguro.tjrj.jus.br/segweb/faces/…'”。 cookie 中没有信息来自哪里,但我有 url。在那种情况下我应该使用InternetCrackUrl并将cookie设置为主机吗?【参考方案2】:

上面的答案是错误的。 CInternetSession 确实处理 cookie。如果本次会话下有http响应 返回一个 Set-Cookie 标头,其中的 cookie 将由会话对象自动保存并返回 在后续请求中发送到服务器。无需使用 SetCookie()。

但有一些注意事项和陷阱:返回的没有过期日期的 Cookie 是会话 Cookie 并且只保存在 MEMORY 中。当 CInternetSession 对象被销毁时,它们将永远消失。

可以在 CInternetSession 对象中使用 SetOption 和禁用 cookie 的请求设置标志。 请参阅标志 INTERNET_OPTION_SUPPRESS_SERVER_AUTH 和 INTERNET_FLAG_NO_COOKIES。小心你没有这样做。

小心缓存。 GET 一次脚本以获取 cookie,然后再次 GET 以打印返回的 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 标头可以改变这种行为。

【讨论】:

您确实知道这是一个 2 年前的问题,对吧?到目前为止,事情可能已经发生了变化。 据我所知,一直都是这样。至少是在提出问题的时候和今天。 是的,但值得注意的是这个答案只适用于 MFC API,问题只提到了 WinINet,而不是 MFC。

以上是关于Wininet 是不是处理 HTTP 标头值“Set-Cookie”?的主要内容,如果未能解决你的问题,请参考以下文章

C++ Wininet 自定义 http 标头

检索 http 标头文件路径值的问题

如何使用 WinINet 查找网页是不是存在

使用wininet的异步请求

Wininet 不向服务器发送 cookie

wininet如何处理cookies