和GET方法一樣,POST方法也是HTTP協議中的一個重要組成部分。POST方法一般用來向目的伺服器發出請求,並附有請求實體。
POST被設計成用統一的方法實現下列功能:
o 對現有資源的注釋(Annotation of existing resources);
o 向電子公告欄、新聞群組,郵件清單或類似討論群組發送訊息;
o 提交資料區塊,如將表格(form)的結果提交給資料處理過程;
o 通過附加操作來擴充資料庫。
o 也可用來上傳檔案。
在所有的HTTP的POST請求中,必須指定合法的內容長度(Content-Length)。
如果HTTP/1.0伺服器在接收到請求訊息內容時無法確定其長度,就會返回400(非法請求)代碼。
應用程式不能緩衝對POST請求的回應,因為做為應用程式來說,它們沒有辦法知道伺服器在未來的請求中將如何回應。
POST方式和GET方法的最大區別就是把發送的資料和URI地址分離。請求參數是在http標題的一個不同部分(名為entity body)傳輸的,這一部分用來傳輸表單資訊,因此必須將Content-type設定為:application/x-www-form- urlencoded。
Post請求格式如下:
POST /login.asp HTTP/1.1
Accept: */*
Referer: http://www.wantsoft.com
Accept-Language: zh-cn,en-us;q=0.5
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; .NET CLR 1.0.3705; .NET CLR 1.1.4322)
Host: www.wantsoft.com
Content-Length: 35
Pragma: no-cache
Cache-Control: no-cache
username=wantsoft&password=password //post的資料
應答格式如下:
HTTP/1.1 200 OK
Server: Microsoft-IIS/5.1
Date: Fri, 05 Dec 2008 15:44:38 GMT
Content-Length: 27
Content-Type: text/html
Cache-control: private
welcome to www.wantsoft.com //網頁的本文內容
使用類CHttpConnection完成http post的代碼如下:
BOOL PostRequest(LPCTSTR lpszURL, // 如:www.wantsoft.com
LPCTSTR lpszObjectName, // 如index.asp
LPCTSTR lpszOptionalData, // 如:username=chrys&password=MyPassword
LPCTSTR lpszReferer, // 如:/modify-new.htm
OUT CString &csResponse)
{
BOOL bRet = FALSE;
CString csHeaders, csOptionalData = lpszOptionalData, csContentLength;
csContentLength.Format ( "Content-Length: %d/n", csOptionalData.GetLength() );
csHeaders += "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/msword, application/x-shockwave-flash, */*/n";
csHeaders += "Referer: http://";
csHeaders += lpszURL;
csHeaders += lpszReferer;
csHeaders += "/n";
csHeaders += "Accept-Language: zh-cn,en-us;q=0.5/n";
csHeaders += "Content-Type: application/x-www-form-urlencoded/n";
csHeaders += "Proxy-Connection: Keep-Alive/n";
csHeaders += "User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; .NET CLR 1.0.3705; .NET CLR 1.1.4322)/n";
csHeaders += "Host: ";
csHeaders += lpszURL;
csHeaders += "/n";
csHeaders += csContentLength;
csHeaders += "Pragma: no-cache/n";
csHeaders += "/r/n";
CHttpFile* pMyHttpFile = NULL;
CHttpConnection* pConnection = NULL;
CInternetSession mySession;
try
{
mySession.SetOption(INTERNET_OPTION_CONNECT_TIMEOUT, 10*1000);
pConnection = mySession.GetHttpConnection(_T(lpszURL));
pMyHttpFile = pConnection->OpenRequest(CHttpConnection::HTTP_VERB_POST, lpszObjectName);
if ( pMyHttpFile->SendRequest(csHeaders,
(LPVOID)(LPCTSTR)csOptionalData, csOptionalData.GetLength()) )
{
DWORD dwStatus;
DWORD dwBuffLen = sizeof(dwStatus);
pMyHttpFile->QueryInfo(HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &dwStatus, &dwBuffLen);
if ( HTTP_STATUS_OK == dwStatus )
{
csResponse.Empty ();
CString myData;
while ( pMyHttpFile->ReadString ( myData ) )
{
csResponse += myData;
}
bRet = TRUE;
}
}
}
catch ( CInternetException* pEx )
{
bRet = FALSE;
TCHAR szErr[1024]={0};
pEx->GetErrorMessage(szErr,1024);
pEx->Delete();
}
if ( pMyHttpFile )
{
pMyHttpFile->Close();
delete pMyHttpFile;
}
if ( pConnection )
{
pConnection->Close();
delete pConnection;
}
mySession.Close();
return bRet;
}