Для эмуляции отправки данных формы, необходимо отправить на сервер заголовок, содержащий правильный Content-Type. Для форм, заголовок Content-Type должен выглядеть следующим образом: Content-Type: application/x-www-form-urlencoded Во многих случаях, сервер может неправильно отреагировать, если в запросе не указан Content-Type. Например, компонент Active Server Pages вебсервера IIS 3.0 проверяет заголовок на наличие в нём 'application/x-www-form- urlencoded' перед тем, как добавить переменные формы в объект "Request.Form". Данный MIME/Content-Type указывает на то, что передаваемые данные это список URL-кодированных переменных формы. Под URL-кодированием понимается, что символы пробела (ASCII 32) будут закодированы как '+', а специальный символ, например, такой как '!' будет закодирован шестнадцатиричной форме как '%21'.
Вот кусок кода, использующего классы MFC WinInet для эмуляции запроса формы POST: CString strHeaders = _T("Content-Type: application/x-www-form-urlencoded"); // URL-кодированные переменные формы - // name = "John Doe", userid = "hithere", other = "P&Q" CString strFormData = _T("name=John+Doe&userid=hithere&other=P%26Q");
CInternetSession session; CHttpConnection* pConnection = session.GetHttpConnection(_T("ServerNameHere")); CHttpFile* pFile = pConnection->OpenRequest(CHttpConnection::HTTP_VERB_POST, _T("FormActionHere")); BOOL result = pFile->SendRequest(strHeaders, (LPVOID)(LPCTSTR)strFormData, strFormData.GetLength()); Без MFC тот же код будет выглядет следующим образом: static TCHAR hdrs[] = _T("Content-Type: application/x-www-form-urlencoded"); static TCHAR frmdata[] = _T("name=John+Doe&userid=hithere&other=P%26Q"); statuc TCHAR accept[] = _T("Accept: */*");
// для понятности, проверка ошибок была удалена HINTERNET hSession = InternetOpen("MyAgent", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); HINTERNET hConnect = InternetConnect(hSession, _T("ServerNameHere"), INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1); HINTERNET hRequest = HttpOpenRequest(hConnect, "POST", _T("FormActionHere"), NULL, NULL, accept, 0, 1); HttpSendRequest(hRequest, hdrs, strlen(hdrs), frmdata, strlen(frmdata)); // закрываем internet-дескрипторы
За более подробной информацией URL-кодированию и формату запроса POST обращайтесь к секции 8.2 в RFC 1866. |