2016-07-30 86 views
0

我想用WinHTTP api Click to the Microsoft Guide在C++中發出一個POST請求,問題是微軟網頁上提供的例子是一個「GET」請求,所以我想出了這個代碼在互聯網上搜索:在WinHttp C++的POST請求

首先我們調用的代碼:

HttpsWebRequestPost("example.com", "/api.php?action=UserLogin", "loginUsername=" + USERNAME + "&loginPassword=" + PASSWORD + "&url=/index.php?page=Portal"); 

然後:

#include <Windows.h> 
#include <WinHttp.h> 
#include <stdio.h> 
#include <iostream> //getchar 
#include <fstream> 

#pragma comment(lib, "winhttp.lib") 

using namespace std; 

std::wstring get_utf16(const std::string &str, int codepage) 
{ 
    if (str.empty()) return std::wstring(); 
    int sz = MultiByteToWideChar(codepage, 0, &str[0], (int)str.size(), 0, 0); 
    std::wstring res(sz, 0); 
    MultiByteToWideChar(codepage, 0, &str[0], (int)str.size(), &res[0], sz); 
    return res; 
} 

string HttpsWebRequestPost(string domain, string url, string dat) 
{ 
    //Extra 
    LPSTR data = const_cast<char *>(dat.c_str());; 
    DWORD data_len = strlen(data); 


    wstring sdomain = get_utf16(domain, CP_UTF8); 
    wstring surl = get_utf16(url, CP_UTF8); 
    string response; 

    DWORD dwSize = 0; 
    DWORD dwDownloaded = 0; 
    LPSTR pszOutBuffer; 
    BOOL bResults = FALSE; 
    HINTERNET hSession = NULL, 
     hConnect = NULL, 
     hRequest = NULL; 

    // Use WinHttpOpen to obtain a session handle. 
    hSession = WinHttpOpen(L"WinHTTP Example/1.0", 
     WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, 
     WINHTTP_NO_PROXY_NAME, 
     WINHTTP_NO_PROXY_BYPASS, 0); 

    // Specify an HTTP server. 
    if (hSession) 
     hConnect = WinHttpConnect(hSession, sdomain.c_str(), 
      INTERNET_DEFAULT_HTTP_PORT, 0); 

    // Create an HTTP request handle. 
    if (hConnect) 
     hRequest = WinHttpOpenRequest(hConnect, L"POST", surl.c_str(), 
      NULL, WINHTTP_NO_REFERER, 
      WINHTTP_DEFAULT_ACCEPT_TYPES, 
      0); 

    // Send a request. 
    if (hRequest) 
     bResults = WinHttpSendRequest(hRequest, 
      WINHTTP_NO_ADDITIONAL_HEADERS, 0, 
      (LPVOID)data, data_len, 
      data_len, 0); 


    // End the request. 
    if (bResults) 
     bResults = WinHttpReceiveResponse(hRequest, NULL); 

    // Keep checking for data until there is nothing left. 
    if (bResults) 
    { 
     do 
     { 
      // Check for available data. 
      dwSize = 0; 
      if (!WinHttpQueryDataAvailable(hRequest, &dwSize)) 
       printf("Error %u in WinHttpQueryDataAvailable.\n", 
        GetLastError()); 

      // Allocate space for the buffer. 
      pszOutBuffer = new char[dwSize + 1]; 
      if (!pszOutBuffer) 
      { 
       printf("Out of memory\n"); 
       dwSize = 0; 
      } 
      else 
      { 
       // Read the data. 
       ZeroMemory(pszOutBuffer, dwSize + 1); 

       if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer, 
        dwSize, &dwDownloaded)) 
        printf("Error %u in WinHttpReadData.\n", GetLastError()); 
       else 
        //printf("%s", pszOutBuffer); 
        response = response + string(pszOutBuffer); 
       // Free the memory allocated to the buffer. 
       delete[] pszOutBuffer; 
      } 
     } while (dwSize > 0); 
    } 

    // Report any errors. 
    if (!bResults) 
     printf("Error %d has occurred.\n", GetLastError()); 

    // Close any open handles. 
    if (hRequest) WinHttpCloseHandle(hRequest); 
    if (hConnect) WinHttpCloseHandle(hConnect); 
    if (hSession) WinHttpCloseHandle(hSession); 

    return response; 

} 

但使用的是Wireshark我只得到:

Hypertext Transfer Protocol 
    POST ***************** HTTP/1.1\r\n 
    Connection: Keep-Alive\r\n 
    User-Agent: WinHTTP Example/1.0\r\n 
    Content-Length: **\r\n 
    Host: ******\r\n 
    \r\n 

任何人都可以幫助我解決這個問題或者知道一個更簡單的方法嗎? 感謝

回答

1

爲了讓PHP(或任何其他後處理語言)來識別POST數據,補充一點:

LPCWSTR additionalHeaders = L"Content-Type: application/x-www-form-urlencoded\r\n"; 
DWORD headersLength = -1; 

bResults = WinHttpSendRequest( hRequest, 
           additionalHeaders, 
           headersLength , 
           (LPVOID)data, 
           data_len, 
           data_len, 
           0); 

的代碼的其餘部分是功能性的,應該工作: enter image description here