Сценарии JavaScript в активных страницах Web

Получение cookie расширением сервера Web


В этом разделе мы приведем пример документа HTML, создающего cookie, а также исходные тексты расширения сервера ISAPI, отображающее на динамически создаваемой странице заголовки HTTP этого документа. Когда браузер создает cookie, расширение сервера получает заголовок HTTP_COOKIE и отображает его.

Наш документ аналогичен описанному ранее в разделе “Записная книжка Cookies Notepad” (рис. 7.8).

Рис. 7.8. Документ HTML, работающий с cookie и расширением сервера ISAPI

Дополнительно мы разместили в документе кнопку Send. С помощью этой кнопки содержимое окна редактирования и заголовок HTTP_COOKIES передается расширению ISAPI сервера Web.

Расширение ISAPI отображает содержимое cookie, как это показано на рис. 7.9.

Рис. 7.9. Результат работы расширения ISAPI

Исходный текст документа HTML вы найдете в листинге 7.4.

Листинг 7.4. Файл chapter7/NotebookISAPI/NotebookISAPI.html

<HTML>

  <HEAD>

    <TITLE>Cookies demo</TITLE>



    <SCRIPT LANGUAGE="JavaScript">

    <!--

    function addCookie(szName,szValue,dtDaysExpires)

    {

      var dtExpires = new Date();

      var dtExpiryDate = "";

      dtExpires.setTime(dtExpires.getTime() + dtDaysExpires * 24 * 60 * 60 * 1000);

      dtExpiryDate = dtExpires.toGMTString();

      document.cookie = szName + "=" + escape(szValue) + ";

expires=" + dtExpiryDate;

    }

    function findCookie(szName)

    {

      var i = 0;

      var nStartPosition = 0;

      var nEndPosition = 0; 

      var szCookieString = document.cookie; 

      var szTemp = "";

      while (i <= szCookieString.length)

      {

        nStartPosition = i;

        nEndPosition = nStartPosition + szName.length;

        if(szCookieString.substring(

            nStartPosition,nEndPosition) == szName)

        {

          nStartPosition = nEndPosition + 1;

          nEndPosition =

            document.cookie.indexOf(";",nStartPosition);


          if(nEndPosition < nStartPosition)

            nEndPosition = document.cookie.length;

          szTemp =

            document.cookie.substring(

            nStartPosition,nEndPosition); 

          return unescape(szTemp);

          break;   

        }

        i++; 

      }

      return "";

    }

    function removeCookie(szName)

    {

      var dtExpires = new Date();

      dtExpires.setTime(dtExpires.getTime() - 1);

      var szValue = findCookie(szName);

      document.cookie = szName + "=" + szValue +

        "; expires=" + dtExpires.toGMTString();

    }

    function btnClick()

    {

      addCookie("MyText",TestForm.Comment.value,10);

    }

    // -->

    </SCRIPT>

  </HEAD>

  <BODY BGCOLOR=white>

    <H1>Cookies Notepad</H1>

    <FORM NAME="TestForm" METHOD=POST ACTION="http://frolov/scripts/ishello.dll?">

      <P><TEXTAREA NAME="Comment"

        ROWS="5" COLS="25" WRAP="physical">

      </TEXTAREA>

      <P><INPUT TYPE="button" VALUE="Store text"

      onClick="btnClick();">

      <INPUT TYPE="button" VALUE="Clear text"

      onClick =

        "removeCookie('MyText');TestForm.Comment.value=''">

      <P><INPUT TYPE=submit VALUE="Send">

    </FORM>   

    <SCRIPT LANGUAGE="JavaScript">

    <!--

      var szMyText="";

      szMyText = findCookie("MyText");

      if(szMyText != "")

      {

        TestForm.Comment.value = szMyText;

      }

    // -->

    </SCRIPT>

  </BODY>

</HTML>

В нем, по сравнению с документом из раздела “Записная книжка Cookies Notepad”, мы добавили параметр ACTION в оператор <FORM>, а также кнопку типа submit с надписью Send. С помощью этой кнопки данные из формы отправляются расширению ISAPI:



  . . .

<FORM NAME="TestForm" METHOD=POST ACTION="http://frolov/scripts/ishello.dll?">

  . . .

<INPUT TYPE=submit VALUE="Send">

. . .

Исходный текст расширения ISAPI представлен в листинге 7.5. Он сделан на базе примера, взятого из 29 тома нашей “Библиотеки системного программиста” (раздел “Приложение ISHELLO” восьмой главы).

Листинг 7.5. Файл chapter7/NotebookISAPI/ishello.c

// ===============================================

// Расширение ISAPI ishello.c

// Пример расширения ISAPI, отображающего

// содержимое cookie

//

// (C) Фролов А.В., 1997, 1998

// E-mail: frolov@glas.apc.org

// WWW:    http://www.glasnet.ru/~frolov

//         или

//         http://www.dials.ccas.ru/frolov

// ===============================================

#include <windows.h>

#include <httpext.h>

// =========================================================

// Функция GetExtensionVersion

// Запись версии интерфейса ISAPI и

// строки описания расширения

// =========================================================

BOOL WINAPI GetExtensionVersion(HSE_VERSION_INFO *pVer)

{

  // Записываем версию интерфейса ISAPI

  pVer->dwExtensionVersion =

    MAKELONG(HSE_VERSION_MINOR,HSE_VERSION_MAJOR );

  // Записываем строку описания расширения

  lstrcpyn(pVer->lpszExtensionDesc,

    "Cookie show ISAPI DLL", HSE_MAX_EXT_DLL_NAME_LEN);

  return TRUE;

}

// =========================================================

// Функция HttpExtensionProc

// =========================================================

DWORD WINAPI HttpExtensionProc(EXTENSION_CONTROL_BLOCK *lpECB)

{

  CHAR  szBuff[4096];

  CHAR  szTempBuf[4096];

 

  DWORD  dwSize;

  // Нулевой код состояния - признак успешного выполнения

  lpECB->dwHttpStatusCode = 0;

  // Записываем в буфер заголовок HTTP и начальный

  // фрагмент формируемого динамически документа HTML

  wsprintf(szBuff,



    "Content-Type: text/html\r\n\r\n"

    "<HTML><HEAD><TITLE>Simple ISAPI Extension</TITLE></HEAD>\n"

    "<BODY BGCOLOR=#FFFFFF><H2>Hello from ISAPI Extension!</H2>\n");

  // Добавляем разделительную линию

  strcat(szBuff, "<HR>");

 

  // Добавляем версию интерфейса ISAPI

  wsprintf(szTempBuf, "<P>Extension Version: %d.%d",

    HIWORD(lpECB->dwVersion), LOWORD(lpECB->dwVersion));

  strcat(szBuff, szTempBuf);

 

  // Название метода передачи данных

  wsprintf(szTempBuf, "<BR>Method: %s", lpECB->lpszMethod);

  strcat(szBuff, szTempBuf);

 

  // Строка параметров запуска расширения ISAPI

  wsprintf(szTempBuf, "<BR>QueryString: %s",

    lpECB->lpszQueryString);

  strcat(szBuff, szTempBuf);

 

  // Физический путь к программному файлу расширения ISAPI

  wsprintf(szTempBuf, "<BR>PathTranslated: %s",

    lpECB->lpszPathTranslated);

  strcat(szBuff, szTempBuf);

  // Полный размер данных, которые нужно получить

  wsprintf(szTempBuf, "<BR>TotalBytes: %d",

    lpECB->cbTotalBytes);

  strcat(szBuff, szTempBuf);

  // Тип данных

  wsprintf(szTempBuf, "<BR>ContentType: %s",

    lpECB->lpszContentType);

  strcat(szBuff, szTempBuf);

  // Отображаем содержимое COOKIE

  strcat(szBuff, "<HR><P><B>Cookie:</B><BR>");

  dwSize = 4096;

  lpECB->GetServerVariable(lpECB->ConnID,

    (LPSTR)"HTTP_COOKIE", (LPVOID)szTempBuf, &dwSize);

  strcat(szBuff, szTempBuf);

  // Конечный фрагмент документа HTML

  strcat(szBuff, "</BODY></HTML>"); 

  // Посылаем содержимое буфера удаленному пользователю

  if(!lpECB->ServerSupportFunction(lpECB->ConnID,

    HSE_REQ_SEND_RESPONSE_HEADER, NULL, NULL,

    (LPDWORD)szBuff))



  {

    // Если послать данные не удалось,

    // завершаем работу нашего расширения ISAPI

    // с кодом ошибки

    return HSE_STATUS_ERROR;

  }

  // Записываем код успешного завершения

  lpECB->dwHttpStatusCode = 200;

 

  // Возвращаем принак успешного завершения 

  return HSE_STATUS_SUCCESS;

}

Файл определения модуля для библиотеки DLL расширения приведен в листинге 7.6.

Листинг 7.6. Файл chapter7/NotebookISAPI/ishello.def

LIBRARY            ishello

DESCRIPTION  'Simple ISAPI DLL'

EXPORTS

    GetExtensionVersion

    HttpExtensionProc

Для извлечения значения cookie, предаваемого расширению через заголовки HTTP, мы использовали функцию GetServerVariable, указав ей в качестве второго параметра имя интересующей нас переменной HTTP_COOKIE:

lpECB->GetServerVariable(lpECB->ConnID,

    (LPSTR)"HTTP_COOKIE", (LPVOID)szTempBuf, &dwSize);

Полученное таким образом значение дописывается в буфер динамически создаваемого документа HTML. Этот буфер впоследствии будет отправлен клиенту при помощи функции ServerSupportFunction.


Содержание раздела