在VC中WININET如何使用HTTP的POST方法

SUMMARY
To properly simulate a Form submission using WinInet, you need to send a header that indicates the proper Content-Type. For Forms, the proper Content-Type header is: Content-Type: application/x-www-form-urlencoded
                 
MORE INFORMATION
     In many cases, the server does not respond appropriately if a Content-Type is not specified. For example, the Active Server Pages component of IIS 3.0 actually checks this header specifically for 'application/x-www-form- urlencoded' before adding form variables to the "Request.Form" object. This MIME/Content-Type indicates that the data of the request is a list of URL- encoded form variables. URL-encoding means that space character (ASCII 32) is encoded as ' ', special character such '!' encoded in hexadecemal form as '!'.

Here is a snippet of code that uses the MFC WinInet classes to simulate a Form POST request:

CString strHeaders  =  _T( " Content-Type: application/x-www-form-urlencoded " );
//  URL-encoded form variables -
//  name = "John Doe", userid = "hithere", other = "P&Q"
CString strFormData  =  _T( " name=John Doe&userid=hithere&other=P&Q " );
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());


Without MFC, the same code translates to straight SDK calls as follows:

static 

TCHAR hdrs[]  =  _T( " Content-Type: application/x-www-form-urlencoded " );


static

TCHAR frmdata[]  =  _T( " name=John Doe&userid=hithere&other=P&Q " );
statuc TCHAR accept[] 
=  _T( " Accept: */* " );
    
//  for clarity, error-checking has been removed
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));


// close any valid internet-handles

我这里有一段程序,用来在一个对话框里显示出一次http     request的原始信息,不过使用Inet     API做的,希望能有帮助。   

void  CHTTPRequestDlg::OnButtonRequest() 
{
    UpdateData(TRUE);   
    HINTERNET hInternet 
= InternetOpen("Mozilla/4.0 (compatible; MSIE 5.0; Windows NT 5.0)"
                                        INTERNET_OPEN_TYPE_DIRECT,
                                        NULL,
                                        NULL,
                                        NULL);   
    HINTERNET hSession 
= InternetConnect(hInternet,
                                        m_strHost,   
                                        m_nPort,
                                        
"username",
                                        
"password",   
                                        INTERNET_SERVICE_HTTP,
                                        
0,
                                        
0);   
    
char* szAccept[] = {"*/*",NULL};
    CString strVerb;
    m_comboVerb.GetWindowText(strVerb);   
    HINTERNET hRequest 
= HttpOpenRequest(hSession,
                                        strVerb,
                                        m_strObject,
                                        NULL,
                                        NULL,
                                        (LPCSTR
*)szAccept,
                                        
0,
                                        
0);   
    
struct   
    
{   
        
char* Language;   
        
char* Encoding;   
        
char* ContentType;   
    }
Headers = {"Accept-Language:zh-cn/r/n",
                
"Accept-Encoding:gzip,deflate/r/n",   
                
"Content-Type:application/x-www-form-urlencoded/r/n"}
;
    
    
if(m_bLanguage)   
    
{
        HttpAddRequestHeaders(hRequest,
                                Headers.Language, 
                                
-1,
                                HTTP_ADDREQ_FLAG_ADD
|HTTP_ADDREQ_FLAG_REPLACE);   
    }

    
if(m_bEncoding)   
    
{
        HttpAddRequestHeaders(hRequest,
                                Headers.Encoding, 
                                
-1,
                                HTTP_ADDREQ_FLAG_ADD
|HTTP_ADDREQ_FLAG_REPLACE);   
    }

    
if(m_bContentType)   
    
{
        HttpAddRequestHeaders(hRequest,
                                Headers.ContentType,
                                
-1,
                                HTTP_ADDREQ_FLAG_ADD
|HTTP_ADDREQ_FLAG_REPLACE);   
    }

    LPCSTR lpAddHeader 
= NULL;
    LPCSTR lpContent 
= NULL;   

    
if(m_strHeaders.GetLength())   
    
{   
        
if(m_strHeaders.Right(2!= "/r/n")   
        
{
            m_strHeaders
+="/r/n";   
        }

        lpAddHeader 
= (LPCSTR)m_strHeaders;   
    }
   
    
if(m_strContent.GetLength() && (strVerb == "POST" || strVerb == "PUT"))   
    
{
        lpContent 
= (LPCSTR)m_strContent;   
    }

    HttpSendRequest(hRequest,
                    lpAddHeader,
                    
-1,
                    (LPVOID)lpContent,
                    m_strContent.GetLength());   
    
    m_editContentGot.SetSel(
0,-1);   
    m_editContentGot.ReplaceSel(
"");   
    
    LPSTR lpszData;        
//buffer for the data   
    DWORD dwSize;        //size of the data available   
    DWORD dwDownloaded; //size of the downloaded data   
    
    
//Set the cursor to an hourglass.   
    SetCursor(LoadCursor(NULL,IDC_WAIT));   
    
    
// This loop handles reading the data.   
    while(1)   
    
{   
        
// The call to InternetQueryDataAvailable determines the amount of 
        
// data available to download.   
        if (!InternetQueryDataAvailable(hRequest,&dwSize,0,0))   
        
{   
            SetCursor(LoadCursor(NULL,IDC_ARROW));   
            
break;   
        }
   
        
else   
        
{     
            
// Allocates a buffer of the size returned by InternetQueryDataAvailable   
            lpszData = new char[dwSize+1];   
            
            
// Reads the data from the HINTERNET handle.   
            if(!InternetReadFile(hRequest,(LPVOID)lpszData,dwSize,&dwDownloaded))   
            
{   
                delete[] lpszData;   
                
break;   
            }
   
            
else   
            
{   
                
// Adds a null terminator to the end of the data buffer   
                lpszData[dwDownloaded]='/0';   
                
                
int nLen = m_editContentGot.GetWindowTextLength();   
                m_editContentGot.SetSel(nLen
-1, nLen-1);   
                m_editContentGot.ReplaceSel(lpszData);   
                
                
// Delete the two buffers   
                delete[] lpszData;   
                
                
// Check the size of the remaining data.   If it is zero, break.   
                if (dwDownloaded == 0)   
                
{
                    
break;   
                }

            }

        }
   
    }
   
    
    
// Close the HINTERNET handle   
    InternetCloseHandle(hRequest);   
    InternetCloseHandle(hSession);   
    InternetCloseHandle(hInternet);   
    
    
// Set the cursor back to an arrow   
    SetCursor(LoadCursor(NULL,IDC_ARROW));   
}


==========================================

使用MFC示例如下:   
    首先设置m_strRequest请求字符串       eg."name=aaa&pass=bbb";               
                    m_strServerName     服务器名称或者IP       eg."www.yahoo.com"   
                    m_strObjectName     请求文件位置     eg.     "pub/aaa.asp"   
        请求的结果存放在m_strHtml中   

void  func()
{   
    CInternetSession m_InetSession(
"session");
    CHttpConnection 
*pServer = NULL;
    CHttpFile
* pFile = NULL;   
    
try
    
{   
        INTERNET_PORT nPort;
        nPort
=80;
        pServer 
= m_InetSession.GetHttpConnection(m_strServerName, nPort);
        pFile 
= pServer->OpenRequest(CHttpConnection::HTTP_VERB_POST,m_strObjectName);
        
char szHeaders[100];
        strcpy(szHeaders,
"Accept: text*/*/r/nContent-Type: application/x-www-form-urlencoded");
        pFile
->AddRequestHeaders(szHeaders);
        
        pFile
->SendRequestEx(m_strRequest.GetLength());   
        pFile
->WriteString(m_strRequest);//重要-->m_Request 中有"name=aaa&name2=BBB&"
        pFile->EndRequest();
        DWORD dwRet;
        pFile
->QueryInfoStatusCode(dwRet);
        CString str;
        
        m_Mutex.Lock();
        m_strHtml
="";
        
char szBuff[1024];

        
if (dwRet == HTTP_STATUS_OK)
        
{
            UINT nRead;   
            
while ((nRead = pFile->Read(szBuff,1023))>0)   
            
{   
                m_strHtml 
+= CString(szBuff,nRead);   
            }

        }

        m_Mutex.Unlock();   
        
        delete pFile;   
        delete pServer;   
    }
   
    
catch (CInternetException* e)
    
{   
        CString s;   
        s.Format(
"Internet Exception/r/nm_dwError%u,m_dwContextError%u",e->m_dwError,e->m_dwContext);   
        AfxMessageBox(s);   
        
//catch errors from WinInet   
    }
   
}


============================

1、获得WebBrowser     Control的DWebBrowserEvents2::DocumentComplete事件   
    2、在DWebBrowserEvents2::DocumentComplete事件中根据IWebBrowser2::Document获得IHTMLDocument2   
    3、IHTMLDocument2::forms得到IHTMLElementCollection   
    4、在IHTMLElementCollection中根据name、tagName、ID得到指定的IHTMLElement   
    5、从IHTMLElement得到IHTMLFormElement   
    6、执行IHTMLFormElement::submit

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值