65.9K
CodeProject 正在变化。 阅读更多。
Home

发现 ISAPI。处理 Cookie。

starIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

1.00/5 (2投票s)

2002 年 7 月 15 日

5分钟阅读

viewsIcon

109558

downloadIcon

724

本文介绍了一种从 ISAPI 扩展向客户端浏览器发送 Cookie 的方法。

Sample Image

引言

本文介绍了一种从 ISAPI 扩展向客户端浏览器发送 Cookie 的方法。还提供了一种检索和可视化 Cookie 的简单方法。

什么是 Cookie?Cookie 是一种用于在用户计算机上存储持久化状态信息的小型信息包。在 HTTP 协议下,Cookie 是服务器或脚本在客户端工作站上维护状态信息的手段。

当 HTTP 请求中的 Cookie 的域和路径与请求匹配时,该请求中会包含 Cookie 标头。

HTTP Cookie 为服务器提供了一种在客户端应用程序的系统上存储和检索状态信息的机制。这种机制允许 Web 应用程序存储有关选定项目、用户偏好设置、注册信息和其他以后可以检索的信息。

与 Cookie 相关的标头

有两个与 Cookie 相关的 HTTP 标头:Set-CookieCookieSet-Cookie 标头由服务器响应 HTTP 请求发送,用于在用户系统上创建 Cookie。如果客户端应用程序发送到服务器的 HTTP 请求中包含匹配的域和路径的 Cookie,则会包含 Cookie 标头

Set-Cookie 标头

Set-Cookie 响应标头使用以下格式:

Set-Cookie: <name>=<value>[; <name>=<value>]...
[; expires=<date>][; domain=<domain_name>]
[; path=<some_path>][; secure]

Set-Cookie 响应标头中必须包含一个或多个遵循 <name>=<value> 模式的字符串序列(以分号分隔)。服务器可以使用这些字符串序列在客户端系统上存储数据。

到期日期通过使用 expires=<date> 格式设置,其中 <date> 是格林威治标准时间 (GMT) 的到期日期。如果未设置到期日期,则 Cookie 在 Internet 会话结束后过期。否则,Cookie 将保留在缓存中直到到期日期。日期必须遵循 DAY, DD-MMM-YYYY HH:MM:SS GMT 格式,其中 DAY 是星期几(Sun, Mon, Tue, Wed, Thu, Fri, Sat),DD 是月份中的第几天(例如,第一个月的第一天为 01),MMM 是月份的三字母缩写(Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec),YYYY 是年份,HH 是 24 小时制的小时值(例如,22 表示下午 10:00),MM 是分钟值,SS 是秒值。

使用 domain=<domain_name> 模式指定域名是持久化 Cookie 的可选设置,用于指示 Cookie 有效的域名后缀。指定域名的会话 Cookie 将被拒绝。如果指定的域名后缀与请求匹配,则 Cookie 会尝试匹配路径以确定是否发送该 Cookie。例如,如果域名后缀是 .microsoft.com,则会检查对 home.microsoft.comsupport.microsoft.com 的请求,以确定指定的模式是否与请求匹配。域名必须至少包含两个或三个点,以防止为 .com.educo.jp 等广泛使用的域名后缀设置 Cookie。允许的域名类似于 .microsoft.com.someschool.edu.someserver.co.jp。只有指定域内的主机才能为该域设置 Cookie。

使用 path=<some_path> 模式设置路径是可选的,可用于指定 Cookie 有效的统一资源定位符 (URL) 的子集。如果指定了路径,则该 Cookie 对于匹配该路径的任何请求都有效。例如,如果指定的路径是 /example,则 /examplecode/example/code.htm 的请求都会匹配。如果未指定路径,则假定路径与 Set-Cookie 标头关联的资源路径相同。

Cookie 还可以被标记为安全,这表示 Cookie 只能发送到 HTTPS 服务器。

Cookie 标头

Cookie 标头包含在任何 Cookie 的域和路径与请求匹配的 HTTP 请求中。Cookie 标头具有以下格式:

Cookie: <name>=<value> [;<name>=<value>]...

使用 <name>=<value> 格式的一个或多个字符串序列包含在 Cookie 中设置的信息。

Cookie 标头示例

"Set-Cookie:Test=test_value; expires=Sat, 01-Jan-2000 00:00:00 GMT; path=/;"

存储 Cookie

Netscape Navigator 存储 Cookie 的方式与 Internet Explorer 不同,尽管它捕获了服务器的相同信息。Internet Explorer 将每个 Cookie 存储在自己的文件中(您可以自己查看,您的 Cookie 通常存储在 Windows system 文件夹的 Temporary Internet Files 目录中),而 Netscape Navigator 则将每个 Cookie 存储在一个名为 cookies.txt 的文件中。

Netscape Navigator 将每个 Cookie 存储在名为 cookies.txt 的单个文件中。(如果您使用的是 Nav3,cookies.txt 通常位于 C:\Program Files\Netscape\Nav3 目录中;Nav4 根据注册的计算机用户文件存储其 Cookie,在我的情况下是 C:\Program Files\Netscape\Users\user。)

功能

默认方法会在浏览器加载一个简单的表单,用户可以在其中输入他们想要的 Cookie 名称/值对。所有工作都在 GetCookie 方法中完成。为了能够将 Cookie 值写入客户端计算机,我们必须告知 IIS 服务器不要写入其自己的标头。

   //Turn off sending header by MFC.
   pCtxt->m_bSendHeaders = FALSE;

包含 Cookie 的标头将由我们的程序使用 ServerSupportFunction HTTP 函数写入客户端计算机。

   // Send our own headers.
   if (!pCtxt->ServerSupportFunction (HSE_REQ_SEND_RESPONSE_HEADER, 
         NULL, &dwSize, (LPDWORD ) szHeaders))
   {  
      ISAPITRACE1 ("ServerSupportFunction failed: %d\n", 
               GetLastError()); // Report an error.
      return;
   }

HTML 表单中的参数值将通过 POST HTTP 数据传输在 GetCookie 方法中接收,然后写入客户端。

//add the user input cookie
//attention, the entry name in 
//vector collection is "DATA"
bstrToken = L"DATA"; 
index = vecServerCtx.Find(bstrToken);
if (index > -1)
{
    //get a map list from the POST data values
    map = vecServerCtx[index].GetValueAsMap(); 
    if(!map.empty())
    {
        //get the current parameter name
        bstrFormCookieName = map[L"FormCookieName"]; 
        //get the current parameter value
        bstrFormCookieValue = map[L"FormCookieValue"];

        wsprintf(szHeader, "Set-Cookie: %s=%s\r\n", 
            (LPCTSTR)bstrFormCookieName, 
            (LPCTSTR)bstrFormCookieValue);
        //add that cookie to the header list
        strcat(szHeaders, szHeader);
    }
}

作为示例考虑,在 GetCookie 方法中写入了另外 2 个 Cookie,一个简单的 Cookie 和一个带时间到期的 Cookie。

在浏览器中,始终会显示来自服务器上下文向量集合的实际客户端 Cookie 值,

来自 Cookie 映射集合的独立的、单个的 Cookie 值,

以及从表单接收的 POST 数据。同样,映射集合用于访问单个参数值。

最后,HTML 表单会再次写入浏览器,使用户能够输入/修改 Cookie。

//output again the form to input another cookie
   dwLen = strForm.GetLength();
   pCtxt->WriteClient( (void*)(LPCTSTR)strForm, &dwLen, 0);

本文还提供了一个用于执行服务器重定向的函数。

© . All rights reserved.