zoukankan      html  css  js  c++  java
  • MFC中发送HTTP或HTTPS请求

    基本知识

    HTTP(超文本传输协议)
    HTTPS(超文本传输安全协议)
    URL(统一资源定位器)

    例子

    1. 一个简单的例子

    #include <afxinet.h>
    #include <string>
    
    bool testHttp(const CString& strUrl, const BYTE* data, int nBytes, CString& strReceive)
    {
        // 解析Url
        // 例如:https://www.cnblogs.com/Zender/p/7596730.html
        DWORD dwServiceType;        // 协议类型:http/https    AFX_INET_SERVICE_HTTP (3)    AFX_INET_SERVICE_HTTPS (4107)
        CString strServer;            // Host    例如:www.cnblogs.com 或者 192.168.10.9
        CString strObject;            // other   例如:/Zender/p/7596730.html
        INTERNET_PORT wPort;        // 端口号   http的默认端口号是80,https的默认端口号是443
        if (!AfxParseURL(strUrl, dwServiceType, strServer, strObject, wPort))
        {
            //解析Url失败
            return false;
        }
        CInternetSession session; // 创建会话
        const int nTimeOut = 10 * 1000;  // 超时设置为 10s
        session.SetOption(INTERNET_OPTION_CONNECT_TIMEOUT, nTimeOut);
        session.SetOption(INTERNET_OPTION_CONNECT_RETRIES, 2);
        CHttpConnection* pConn = NULL;
        CHttpFile* pFile = NULL;
        if (AFX_INET_SERVICE_HTTP == dwServiceType)
        {
            pConn = session.GetHttpConnection(strServer, wPort);
            pFile = pConn->OpenRequest(CHttpConnection::HTTP_VERB_POST, strObject);
        }
        else if (AFX_INET_SERVICE_HTTPS == dwServiceType)
        {
            pConn = session.GetHttpConnection(strServer, INTERNET_FLAG_SECURE, wPort);
            pFile = pConn->OpenRequest(CHttpConnection::HTTP_VERB_POST, strObject, NULL, 1, NULL, NULL,
                INTERNET_FLAG_SECURE | INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_RELOAD |
                INTERNET_FLAG_IGNORE_CERT_CN_INVALID | INTERNET_FLAG_IGNORE_CERT_DATE_INVALID);//SECURITY_FLAG_IGNORE_UNKNOWN_CA
        }
        else
        {
            //其他协议返回
            return false;
        }
        try
        {
            CString strHeaders("Content-Type: application/x-www-form-urlencoded");//请求头
            BOOL bRet = pFile->SendRequest(strHeaders, (LPVOID)data, nBytes);
            if (!bRet)
            {
                goto Failure_label;
            }
            DWORD dwStatusCode;
            bRet = pFile->QueryInfoStatusCode(dwStatusCode);
            if (HTTP_STATUS_OK != dwStatusCode)//#define HTTP_STATUS_OK  200
            {
                CString strErrInfo;
                pFile->QueryInfo(HTTP_QUERY_RAW_HEADERS, strErrInfo);
                goto Failure_label;
            }
            std::string sReceive;
            char buffer[1024] = { 0 };
            for (UINT len = 0; (len = pFile->Read(buffer, sizeof(buffer))) > 0; memset(buffer, 0, sizeof(buffer)))
            {
                std::string s(buffer, len);
                sReceive += s;
            }
            strReceive = CStringA(sReceive.c_str(), sReceive.length());//注意:若sReceive中有,可能会截断
            return true;
        }
        catch (CInternetException& e)
        {
            TCHAR szErr[512] = { 0 };
            e.GetErrorMessage(szErr, sizeof(szErr));
            CString strErrInfo;
            pFile->QueryInfo(HTTP_QUERY_RAW_HEADERS, strErrInfo);
            goto Failure_label;
        }
    
    Failure_label:
        if (pConn)
        {
            pConn->Close();
            delete pConn;
            pConn = NULL;
        }
        if (pFile)
        {
            pFile->Close();
            delete pFile;
            pFile = NULL;
        }
        return false;
    }
    BOOL CtestMFCHttpApp::InitInstance()
    {
        CString url("https://www.cnblogs.com/12Zender/p/7596730.html");
        CString strReceive;
        BYTE* data = (BYTE*)"123";
        testHttp(url,data,3,strReceive);
    }
    View Code

    2. 网上别人封装的类(MFC - HTTP(post与get)请求网页内容或图片

    /////////////////  CHttpClient.h //////////////
    
    #ifndef HTTPCLIENT_H
    #define HTTPCLIENT_H
     
    #include <afxinet.h>
     
    #define  IE_AGENT  _T("Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)")
    #define  REQ_CODE_UTF8  _T("UTF-8")
    #define  REQ_CODE_GBK   _T("GBK")
     
    // 操作成功
    #define SUCCESS        0
    // 操作失败
    #define FAILURE        1
    // 操作超时
    #define OUTTIME        2
     
    class CHttpClient
    {
    public:
        CHttpClient(const CString& szReqCode = REQ_CODE_UTF8,LPCTSTR strAgent = IE_AGENT);
        virtual ~CHttpClient(void);
     
        int HttpGet(LPCTSTR strUrl, CString &strResponse);
        int HttpGetImg(LPCTSTR strUrl, LPCTSTR imgPath);
        int HttpPost(LPCTSTR strUrl, CString &strResponse, LPCTSTR strPostData);
     
    private:
        int ExecuteRequest(LPCTSTR strMethod, LPCTSTR strUrl, LPCTSTR strPostData, CString &strResponse, LPCTSTR imgPath);
        void Clear();
        CStringA GetReqData(const CString&  szReqData);
        CString  GetResData(const CStringA& szResData);
    private:
        CInternetSession *m_pSession;
        CHttpConnection *m_pConnection;
        CHttpFile *m_pFile;
        CString m_szReqCode;
    };
     
    #endif
    
    
    
    ///////////////////// CHttpClient.cpp  ///////////////////
    ////////////////////////////////// HttpClient.cpp
    #include "StdAfx.h"
    #include "HttpClient.h"
     
    #define  BUFFER_SIZE       1024
     
    #define  NORMAL_CONNECT             INTERNET_FLAG_KEEP_CONNECTION
    #define  SECURE_CONNECT             NORMAL_CONNECT | INTERNET_FLAG_SECURE
    #define  NORMAL_REQUEST             INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE
    #define  SECURE_REQUEST             NORMAL_REQUEST | INTERNET_FLAG_SECURE | 
                                        INTERNET_FLAG_IGNORE_CERT_CN_INVALID| 
                                        INTERNET_FLAG_IGNORE_CERT_DATE_INVALID 
     
    CHttpClient::CHttpClient(const CString& szReqCode,LPCTSTR strAgent)
    {
        m_pSession = new CInternetSession(strAgent);
        m_szReqCode = szReqCode;
        m_pConnection = NULL;
        m_pFile = NULL;
    }
     
    CHttpClient::~CHttpClient(void)
    {
        Clear();
        if (NULL != m_pSession)
        {
            m_pSession->Close();
            delete m_pSession;
            m_pSession = NULL;
        }
    }
     
    void CHttpClient::Clear()
    {
        if (NULL != m_pFile)
        {
            m_pFile->Close();
            delete m_pFile;
            m_pFile = NULL;
        }
     
        if (NULL != m_pConnection)
        {
            m_pConnection->Close();
            delete m_pConnection;
            m_pConnection = NULL;
        }
    }
     
    int CHttpClient::ExecuteRequest(LPCTSTR strMethod, LPCTSTR strUrl, LPCTSTR strPostData, CString &strResponse, LPCTSTR imgPath = NULL)
    {
        DWORD dwFlags;
        CString strServer;
        CString strObject;
        DWORD dwServiceType;
        INTERNET_PORT nPort;
        strResponse = _T("");
     
     
        AfxParseURL(strUrl, dwServiceType, strServer, strObject, nPort);
     
        if (AFX_INET_SERVICE_HTTP != dwServiceType && AFX_INET_SERVICE_HTTPS != dwServiceType)
        {
            return FAILURE;
        }
        try
        {
            m_pConnection = m_pSession->GetHttpConnection(strServer,
                dwServiceType == AFX_INET_SERVICE_HTTP ? NORMAL_CONNECT : SECURE_CONNECT,nPort);
            m_pFile = m_pConnection->OpenRequest(strMethod, strObject, NULL, 1, NULL, NULL,
                (dwServiceType == AFX_INET_SERVICE_HTTP ? NORMAL_REQUEST : SECURE_REQUEST));
            if (AFX_INET_SERVICE_HTTPS == dwServiceType)
            {
                m_pFile->QueryOption(INTERNET_OPTION_SECURITY_FLAGS, dwFlags);
                dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA;
                m_pFile->SetOption(INTERNET_OPTION_SECURITY_FLAGS, dwFlags);
            }
            m_pFile->AddRequestHeaders(_T("Accept: *,*/*"));
            m_pFile->AddRequestHeaders(_T("Accept-Language: zh-cn"));
            m_pFile->AddRequestHeaders(_T("Content-Type: application/x-www-form-urlencoded"));
            m_pFile->AddRequestHeaders(_T("Accept-Encoding: deflate"));
            if (strPostData != NULL) {
                CStringA strData = GetReqData(strPostData);
                m_pFile->SendRequest(NULL, 0, (LPVOID)(LPCSTR)strData, strlen(strData));
            }
            else {
                m_pFile->SendRequest();
            }
            
            char szChars[BUFFER_SIZE + 1] = { 0 };
            CStringA strRawResponse = "";
            UINT nReaded = 0;
     
            if (imgPath == NULL) {
                while ((nReaded = m_pFile->Read((void*)szChars, BUFFER_SIZE)) > 0)
                {
                    szChars[nReaded] = '';
                    strRawResponse += szChars;
                    memset(szChars, 0, BUFFER_SIZE + 1);
                }
                strResponse = GetResData(strRawResponse);
            } else {
                CFile f;
                f.Open(imgPath, CFile::modeCreate|CFile::modeWrite|CFile::typeBinary);
                while ((nReaded = m_pFile->Read((void*)szChars, BUFFER_SIZE)) > 0)
                {
                    szChars[nReaded] = '';
                    f.Write(szChars, BUFFER_SIZE);
                    memset(szChars, 0, BUFFER_SIZE + 1);
                }
                f.Close();
            }
            Clear();
        }
        catch (CInternetException* e)
        {
            Clear();
            DWORD dwErrorCode = e->m_dwError;
            e->Delete();
            DWORD dwError = GetLastError();
     
            if (ERROR_INTERNET_TIMEOUT == dwErrorCode)
            {
                return OUTTIME;
            }
            else
            {
                return FAILURE;
            }
        }
        return SUCCESS;
    }
     
    int CHttpClient::HttpGet(LPCTSTR strUrl, CString &strResponse)
    {
        return ExecuteRequest(_T("GET"), strUrl, NULL, strResponse);
    }
     
    int CHttpClient::HttpPost(LPCTSTR strUrl, CString &strResponse, LPCTSTR strPostData)
    {
        return ExecuteRequest(_T("POST"), strUrl, strPostData, strResponse);
    }
     
    int CHttpClient::HttpGetImg(LPCTSTR strUrl, LPCTSTR imgPath)
    {
        CString str;
        return ExecuteRequest(_T("GET"), strUrl, NULL, str,imgPath);
    }
    CStringA CHttpClient::GetReqData(const CString& szReqData)
    {
        // 预算-缓冲区中多字节的长度    
        int ansiiLen = WideCharToMultiByte(CP_UTF8, 0, szReqData, -1, NULL, 0, NULL, NULL);
        char * pAssii = (char*)malloc(sizeof(char)*ansiiLen);
        // 开始向缓冲区转换字节    
        WideCharToMultiByte(CP_UTF8, 0, szReqData, -1, pAssii, ansiiLen, NULL, NULL);
        CStringA szRet(pAssii);
        free(pAssii);
        return szRet;
    }
    CString CHttpClient::GetResData(const CStringA& szResData)
    {
        if (m_szReqCode == REQ_CODE_GBK)
            return CString(szResData);
        // 预算-缓冲区中宽字节的长度    
        int unicodeLen = MultiByteToWideChar(CP_UTF8, 0, szResData, -1, NULL, 0);
        wchar_t *pUnicode = (wchar_t*)malloc(sizeof(wchar_t)*unicodeLen);
        // 开始向缓冲区转换字节    
        MultiByteToWideChar(CP_UTF8, 0, szResData, -1, pUnicode, unicodeLen);
        CString szRet(pUnicode);
        free(pUnicode);
        return szRet;
    }
    
    
    
    
    ///////////////////// 使用方法  ///////////////////
        CHttpClient http;
        CString url;
        GetDlgItemText(IDC_EDIT2, url);
        CString str;
        http.HttpGet(url, str);
        AfxMessageBox(str);
    View Code

    转载:https://www.cnblogs.com/Ray-chen/archive/2011/12/14/2287812.html

    一、建立会话(Session)对象:

           CInternetSession mysession;

    二、连接到Http服务器:

          CHttpConnection *myconn=mysession.GetHttpConnection("www.baidu.com");

    三、打开Http请求:

          CHttpFile *myfile=myconn->OpenRequest("GET","/index.html");

    四、发送Http请求:

          myfile->SendRequest();

    五、从服务器读取字节流(bytes):

          CString mystr;
          CString tmp;
          while(myfile->ReadString(tmp))
          {
               mystr+=tmp;
          }

    六、释放资源:

         myfile->Close();
          myconn->Close();
         mysession.Close();
         delete myfile;
         delete myconn;
         myfile=0;
         myconn=0;

         步骤基本如上,上例各函数参数主要使用默认参数,具体函数声明请查阅MSDN。另外别忘了异常处理!

    1、下载文件
    Download(const CString& strFileURLInServer, //待下载文件的URL
    const CString & strFileLocalFullPath)//存放到本地的路径
    {
     ASSERT(strFileURLInServer != "");
     ASSERT(strFileLocalFullPath != "");
     CInternetSession session;
     CHttpConnection* pHttpConnection = NULL;
     CHttpFile* pHttpFile = NULL;
     CString strServer, strObject;
     INTERNET_PORT wPort;

     DWORD dwType;
     const int nTimeOut = 2000;
     session.SetOption(INTERNET_OPTION_CONNECT_TIMEOUT, nTimeOut); //重试之间的等待延时
     session.SetOption(INTERNET_OPTION_CONNECT_RETRIES, 1);   //重试次数
     char* pszBuffer = NULL;  

     try
     {
      AfxParseURL(strFileURLInServer, dwType, strServer, strObject, wPort);
      pHttpConnection = session.GetHttpConnection(strServer, wPort);
      pHttpFile = pHttpConnection->OpenRequest(CHttpConnection::HTTP_VERB_GET, strObject);
      if(pHttpFile->SendRequest() == FALSE)
       return false;
      DWORD dwStateCode;

      pHttpFile->QueryInfoStatusCode(dwStateCode);
      if(dwStateCode == HTTP_STATUS_OK)
      {
        HANDLE hFile = CreateFile(strFileLocalFullPath, GENERIC_WRITE,
             FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
             NULL);  //创建本地文件
       if(hFile == INVALID_HANDLE_VALUE)
       {
        pHttpFile->Close();
        pHttpConnection->Close();
        session.Close();
        return false;
       }
     
       char szInfoBuffer[1000];  //返回消息
       DWORD dwFileSize = 0;   //文件长度
       DWORD dwInfoBufferSize = sizeof(szInfoBuffer);
       BOOL bResult = FALSE;
       bResult = pHttpFile->QueryInfo(HTTP_QUERY_CONTENT_LENGTH,
               (void*)szInfoBuffer,&dwInfoBufferSize,NULL);

       dwFileSize = atoi(szInfoBuffer);
       const int BUFFER_LENGTH = 1024 * 10;
       pszBuffer = new char[BUFFER_LENGTH];  //读取文件的缓冲
       DWORD dwWrite, dwTotalWrite;
       dwWrite = dwTotalWrite = 0;
       UINT nRead = pHttpFile->Read(pszBuffer, BUFFER_LENGTH); //读取服务器上数据

       while(nRead > 0)
       {
        WriteFile(hFile, pszBuffer, nRead, &dwWrite, NULL);  //写到本地文件
        dwTotalWrite += dwWrite;
        nRead = pHttpFile->Read(pszBuffer, BUFFER_LENGTH);
       }

       delete[]pszBuffer;
       pszBuffer = NULL;
       CloseHandle(hFile);
      }
      else
      {
       delete[]pszBuffer;
       pszBuffer = NULL;
       if(pHttpFile != NULL)
       {
        pHttpFile->Close();
        delete pHttpFile;
        pHttpFile = NULL;
       }
       if(pHttpConnection != NULL)
       {
        pHttpConnection->Close();
        delete pHttpConnection;
        pHttpConnection = NULL;
       }
       session.Close();
        return false;
      }
     }
     catch(...)
     {
      delete[]pszBuffer;
      pszBuffer = NULL;
      if(pHttpFile != NULL)
      {
       pHttpFile->Close();
       delete pHttpFile;
       pHttpFile = NULL;
      }
      if(pHttpConnection != NULL)
      {
       pHttpConnection->Close();
       delete pHttpConnection;
       pHttpConnection = NULL;
      }
      session.Close();
      return false;
     }

     if(pHttpFile != NULL)
      pHttpFile->Close();
     if(pHttpConnection != NULL)
      pHttpConnection->Close();
     session.Close();
     return true;
    }

    2、上传文件
    bool Download(const CString& strFileURLInServer, //待下载文件的URL
    const CString & strFileLocalFullPath)//存放到本地的路径
    {
    ASSERT(strFileURLInServer != "");
    ASSERT(strFileLocalFullPath != "");
    CInternetSession session;
    CHttpConnection* pHttpConnection = NULL;
    CHttpFile* pHttpFile = NULL;
    CString strServer, strObject;
    INTERNET_PORT wPort;
    bool bReturn = false;

    DWORD dwType;
    const int nTimeOut = 2000;
    session.SetOption(INTERNET_OPTION_CONNECT_TIMEOUT, nTimeOut); //重试之间的等待延时
    session.SetOption(INTERNET_OPTION_CONNECT_RETRIES, 1); //重试次数
    char* pszBuffer = NULL;

    try
    {
    AfxParseURL(strFileURLInServer, dwType, strServer, strObject, wPort);
    pHttpConnection = session.GetHttpConnection(strServer, wPort);
    pHttpFile = pHttpConnection->OpenRequest(CHttpConnection::HTTP_VERB_GET, strObject);
    if(pHttpFile->SendRequest() == FALSE)
    return false;
    DWORD dwStateCode;

    pHttpFile->QueryInfoStatusCode(dwStateCode);
    if(dwStateCode == HTTP_STATUS_OK)
    {
    HANDLE hFile = CreateFile(strFileLocalFullPath, GENERIC_WRITE,
    FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
    NULL); //创建本地文件
    if(hFile == INVALID_HANDLE_VALUE)
    {
    pHttpFile->Close();
    pHttpConnection->Close();
    session.Close();
    return false;
    }

    char szInfoBuffer[1000]; //返回消息
    DWORD dwFileSize = 0; //文件长度
    DWORD dwInfoBufferSize = sizeof(szInfoBuffer);
    BOOL bResult = FALSE;
    bResult = pHttpFile->QueryInfo(HTTP_QUERY_CONTENT_LENGTH,
    (void*)szInfoBuffer,&dwInfoBufferSize,NULL);

    dwFileSize = atoi(szInfoBuffer);
    const int BUFFER_LENGTH = 1024 * 10;
    pszBuffer = new char[BUFFER_LENGTH]; //读取文件的缓冲
    DWORD dwWrite, dwTotalWrite;
    dwWrite = dwTotalWrite = 0;
    UINT nRead = pHttpFile->Read(pszBuffer, BUFFER_LENGTH); //读取服务器上数据

    while(nRead > 0)
    {
    WriteFile(hFile, pszBuffer, nRead, &dwWrite, NULL); //写到本地文件
    dwTotalWrite += dwWrite;
    nRead = pHttpFile->Read(pszBuffer, BUFFER_LENGTH);
    }

    delete[]pszBuffer;
    pszBuffer = NULL;
    CloseHandle(hFile);
    bReturn = true;
    }
    }
    catch(CInternetException* e)
    {
    TCHAR tszErrString[256];
    e->GetErrorMessage(tszErrString, ArraySize(tszErrString));
    TRACE(_T("Download XSL error! URL: %s,Error: %s"), strFileURLInServer, tszErrString);
    e->Delete();
    }
    catch(...)
    {
    }

    if(pszBuffer != NULL)
    {
    delete[]pszBuffer;
    }
    if(pHttpFile != NULL)
    {
    pHttpFile->Close();
    delete pHttpFile;
    }
    if(pHttpConnection != NULL)
    {
    pHttpConnection->Close();
    delete pHttpConnection;
    }
    session.Close();
    return bReturn;

    ******************

    常记溪亭日暮,沉醉不知归路。兴尽晚回舟,误入藕花深处。争渡,争渡,惊起一滩鸥鹭。

    昨夜雨疏风骤,浓睡不消残酒。试问卷帘人,却道海棠依旧。知否?知否?应是绿肥红瘦。
  • 相关阅读:
    7-4
    7-3
    第五章例5-2
    第五章例5-1
    第四章例4-12
    第四章例4-11
    第四章例4-10
    第四章例4-9
    第四章例4-8
    第四章例4-7
  • 原文地址:https://www.cnblogs.com/htj10/p/12679300.html
Copyright © 2011-2022 走看看