WinHTTP 中的 Cookie 处理

HTTP 会话数据在请求或响应的 Cookie 标头中在客户端和服务器之间传递。 服务器在响应的 Set-cookie 标头中将 Cookie 发送到客户端,WinHTTP API 将服务器 Cookie 重新发送到请求的 Cookie 标头中的服务器。 默认情况下,在 WinHTTP 中实现 rfc 2109 (HTTP 状态管理机制) 中所述的 Cookie 处理规范。 WinHTTP 不支持 rfc 2964 中介绍的最新 Cookie 处理规范。

WinHTTP 从服务器Set-Cookie标头获取 Cookie,并按会话将其存储在缓存中。 此 Cookie 在目标与 Cookie 源匹配的同一 WinHTTP 会话中的后续请求上重新发出。 WinHTTP API 为请求中的每个段重新生成请求 Cookie 标头。

以下列表介绍了 WinHTTP 客户端应用程序可用于处理 Cookie 的多个选项:

  • 自动 Cookie 处理 - WinHTTP 自动处理 Cookie,客户端应用程序不执行任何自定义 Cookie 处理。
  • 禁用自动 Cookie 处理 - WinHTTP API 中的自动 Cookie 处理处于禁用状态,并且不会发送任何 Cookie。
  • 手动指定所有 Cookie - 禁用自动 Cookie 处理,客户端应用程序会为会话中的每个请求添加或删除所有 Cookie 标头。
  • 手动和自动 Cookie 处理 - 自动和手动 Cookie 处理相结合。

若要禁用 Cookie 处理,WinHTTP 客户端应用程序调用 WinHttpSetOption 函数,其中 dwOption 参数设置为 WINHTTP_OPTION_DISABLE_FEATURElpBuffer 参数设置为 WINHTTP_DISABLE_COOKIEShInternet 参数必须是请求句柄。 在已发送上一个请求的请求句柄上禁用 Cookie 处理时,客户端应在发送下一个请求之前使用 WinHttpAddRequestHeaders 函数手动删除现有请求 Cookie 标头。 有关详细信息,请参阅 删除 Cookie 标头

注意

禁用自动模式后,客户端应用程序必须在会话上设置所有 Cookie。

手动指定所有 Cookie

禁用自动 Cookie 处理后,WinHTTP 客户端应用程序可以选择手动指定所有 Cookie。 若要手动设置 Cookie,应用程序会调用 WinHttpAddRequestHeaders ,以在 pwszHeaders 参数中指定 Cookie 标头。 客户端应用程序应在重新发送请求之前清除所有 Cookie 标头。

客户端应用程序还应在重定向请求时更改 Cookie 标头。 若要更改重定向请求上的 Cookie,客户端使用 WinHttpSetStatusCallback 指定一个回调函数来响应重定向回调案例。 回调处理程序应通过调用 WinHttpAddRequestHeaders 清除以前在请求上发送的 Cookie。 有关删除 Cookie 标头的详细信息,请参阅 删除 Cookie 标头

WinHTTP 客户端应用程序可以将 WinHTTP 自动 Cookie 处理机制与手动 Cookie 处理相结合。 应用程序在使用 WinHttpSendRequest 函数发送请求之前,将自定义 Cookie 添加到自动生成的 Cookie 标头。 自定义 Cookie 应该是 WinHTTP API 请求中的第一个 Cookie 标头,以便正确缓存 Cookie。 客户端应用程序还应删除在以前请求上发送的 Cookie,然后再在同一请求句柄上重新发送请求。 有关详细信息,请参阅删除 Cookie 标头。

在调用 WinHttpSendRequest 之前添加到请求的 Cookie 包含在代表下一个 WinHttpSendRequestWinHttpReceiveResponse 调用发送的所有 WinHTTP 请求 中。 重定向请求后,客户端应用程序可能需要清除 Cookie 标头。 若要清除重定向请求上的 Cookie,客户端使用 WinHttpSetStatusCallback 指定一个回调函数来响应重定向回调案例。 回调处理程序应通过调用 WinHttpAddRequestHeaders 清除以前在请求上发送的 Cookie。 回调函数可能不会在重定向回调上设置新的自定义 Cookie。 在为下一个 WinHttpSendRequest 调用添加新 Cookie 之前,客户端必须等待 WinHttpReceiveResponse 完成。

WinHTTP 客户端应用程序可能需要在重新发送请求之前清除现有请求 Cookie,以防止在以前请求上发送的 Cookie 再次在当前请求上发送;有关详细信息,请参阅以下说明。 另请注意,在请求句柄上发送第一个请求之前,不必清除 Cookie。 客户端可以通过使用 pwszHeaders 参数中的空 Cookie 标头和 dwModifier 参数中设置的 WINHTTP_ADDREQ_FLAG_REPLACE 标志调用 WinHttpAddRequestHeaders 来清除现有 Cookie。 下面的代码示例演示如何清除请求上的 Cookie 标头。

WinHttpAddRequestHeaders(hRequest, 
                         L"Cookie:", 
                         -1, 
                         WINHTTP_ADDREQ_FLAG_REPLACE);

WinHTTP API 对于早于 Service Pack 2 (SP2) 和 Windows Server 2003 Service Pack 1 (SP1) 的操作系统版本具有不同的 Cookie 处理行为。

**SP2 及更高版本的 Windows XP 以及 SP1 及更高版本的 Windows Server 2003: **

WinHTTP API 清除对请求句柄的先前请求发送的所有 Cookie。 客户端可以在每次调用 WinHttpSendRequest 之前手动添加新的 Cookie 标头。 如果未禁用 WinHTTP API 的自动 Cookie 处理功能,则 WinHTTP API 会将新的 Cookie 标头追加 (,或者如果客户端应用程序未手动添加一个 cookie 标头,) 来自服务器的 Cookie,则 WinHTTP API 将添加一个新的 Cookie 标头。

**SP2 的 Windows XP 和 SP1 的 Windows Server 2003: **

WinHttpReceiveResponse 完成后,WinHTTP API 不会清除请求 Cookie 标头。 在先前请求中发送的 Cookie 将在后续调用 WinHttpSendRequest 时重新发送。 WinHTTP 客户端应用程序应在请求句柄上重新发送请求之前清除现有的 Cookie 标头。