在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 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,
,
);

HINTERNET hRequest = HttpOpenRequest(hConnect, 

                                     "POST",

                                     _T("FormActionHere"), 

                                     NULL, 

                                     NULL, 

                                     accept, 
, 
);

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,
,
);   

    char* szAccept[] = {"*/*",NULL};

    CString strVerb;

    m_comboVerb.GetWindowText(strVerb);   

    HINTERNET hRequest = HttpOpenRequest(hSession,

                                        strVerb,

                                        m_strObject,

                                        NULL,

                                        NULL,

                                        (LPCSTR*)szAccept,
,
);   

    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

 
 
 
 
 
 
 
 
 
 
 
 
 

你可能感兴趣的:(在VC中WININET如何使用HTTP的POST方法)