微软貌似没有提供例子,这里提供简单的使用方法,这里是同步的访问,异步的方法可以看下微软的文档。
#include <stdio.h>
#include <Windows.h>
#include <wininet.h>
#include <string>
#include <map>
#include <vector>
#define USER_AGENT L"WinInetTestCode/1.0"
using namespace std;
//链接需要 wininet.lib
#pragma comment(lib,"wininet.lib")
std::vector<std::wstring> Split(const std::wstring& str, const std::wstring& delim)
{
std::vector<std::wstring> result;
size_t delim_len = delim.length();
std::string::size_type pos1 = 0;
std::string::size_type pos2 = str.find(delim);
while (pos2 != std::string::npos)
{
result.emplace_back(str, pos1, pos2 - pos1);
pos1 = pos2 + delim_len;
pos2 = str.find(delim, pos1);
}
if (pos1 != str.length())
{
result.emplace_back(str, pos1);
}
return result;
}
std::wstring& Trim(std::wstring& s)
{
if (s.empty())
{
return s;
}
s.erase(0, s.find_first_not_of(L" "));
s.erase(s.find_last_not_of(L" ") + 1);
s.erase(0, s.find_first_not_of(L"\t"));
s.erase(s.find_last_not_of(L"\t") + 1);
return s;
}
BOOL SendRequest(const std::wstring& strUrl, //要访问的URL
LPCWSTR lpMothod, //方法 POST GET PUT ...
LPBYTE lpData, //数据
DWORD dwSize, //数据的大小
const std::map<std::wstring, std::wstring>& mapInputHeaders,//发送的HTTP头
DWORD& dwRetCode, //返回的状态
std::map<std::wstring, std::wstring>& mapOutputHeaders,//返回的HTTP头
LPBYTE& lpRetData,//返回的数据Buffer指针,需要调用者使用delete[] 释放
DWORD& dwRetSize) //返回的数据大小
{
lpRetData = nullptr;
dwRetSize = 0;
if (nullptr == lpMothod) {
return FALSE;
}
//0.解析URL,这里为了防止将栈空间用光,最好使用堆内存
//测试代码,一切从简
typedef struct URLDATA
{
WCHAR szServerName[1024];
WCHAR szObjectName[1024];
WCHAR szScheme[64];
}URLDATA,* PURLDATA;
URLDATA urlData;
PURLDATA pUrlData = &urlData;//new URLDATA;
URL_COMPONENTSW urlParse = {0};
urlParse.dwStructSize = sizeof(urlParse);
urlParse.dwHostNameLength = sizeof(pUrlData->szServerName);
urlParse.lpszHostName = pUrlData->szServerName;
urlParse.lpszScheme = pUrlData->szScheme;
urlParse.dwSchemeLength = sizeof(pUrlData->szScheme);
urlParse.lpszUrlPath = pUrlData->szObjectName;
urlParse.dwUrlPathLength = sizeof(pUrlData->szObjectName);
if (!InternetCrackUrl(strUrl.c_str(), strUrl.length(),
0, &urlParse))
{
return FALSE;
}
//1.初始化
LPCTSTR lpszAgent = USER_AGENT;
HINTERNET hInternet = InternetOpen(lpszAgent,
INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
LPCTSTR lpszServerName = urlParse.lpszHostName;//"ssl.google-analytics.com"; //设置server
INTERNET_PORT nServerPort = urlParse.nPort;//INTERNET_DEFAULT_HTTP_PORT;//INTERNET_DEFAULT_HTTPS_PORT; // HTTPS端口443
DWORD dwConnectFlags = 0;
DWORD dwConnectContext = 0;
//2.连接
HINTERNET hConnect = InternetConnect(hInternet,
lpszServerName, nServerPort,
NULL, NULL,
INTERNET_SERVICE_HTTP,
dwConnectFlags, dwConnectContext);
//3.发送请求
LPCTSTR lpszVerb = lpMothod;
LPCTSTR lpszObjectName = urlParse.lpszUrlPath;
LPCTSTR lpszVersion = NULL; // 默认.
LPCTSTR lpszReferrer = NULL; // 没有引用页
LPCTSTR* lplpszAcceptTypes = NULL; // Accpet所有类型.
DWORD dwOpenRequestFlags = INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP |
INTERNET_FLAG_KEEP_CONNECTION |
INTERNET_FLAG_NO_AUTH |
INTERNET_FLAG_NO_COOKIES |
INTERNET_FLAG_NO_UI |
//设置启用HTTPS
INTERNET_FLAG_RELOAD;
//处理HTTPS的情况
if (urlParse.nScheme == INTERNET_SCHEME_HTTPS) {
dwOpenRequestFlags |= INTERNET_FLAG_SECURE;
}
DWORD dwOpenRequestContext = 0;
HINTERNET hRequest = HttpOpenRequest(hConnect, lpszVerb, lpszObjectName, lpszVersion,
lpszReferrer, lplpszAcceptTypes,
dwOpenRequestFlags, dwOpenRequestContext);
for(std::map<std::wstring, std::wstring>::const_iterator itIndex = mapInputHeaders.begin();
itIndex != mapInputHeaders.end(); itIndex++)
{
std::wstring strHeader = itIndex->first + L":" + itIndex->second;
//设置HTTP头
HttpAddRequestHeaders(hRequest, strHeader.c_str(), -1,HTTP_ADDREQ_FLAG_ADD| HTTP_ADDREQ_FLAG_REPLACE);
}
do {
DWORD dwError = 0;
if (!HttpSendRequest(hRequest, NULL, 0, NULL, 0))
{
if (dwError == ERROR_INTERNET_INVALID_CA)
{
DWORD dwFlags;
DWORD dwBuffLen = sizeof(dwFlags);
InternetQueryOption(hRequest, INTERNET_OPTION_SECURITY_FLAGS,
(LPVOID)&dwFlags, &dwBuffLen);
dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA;
InternetSetOption(hRequest, INTERNET_OPTION_SECURITY_FLAGS,
&dwFlags, sizeof(dwFlags));
continue;
}
}
break;
} while (TRUE);
//4.处理返回头数据
//获得HTTP Response Header信息
DWORD dwInfoLevel = HTTP_QUERY_RAW_HEADERS_CRLF;
DWORD dwInfoBufferLength = 4094;
PBYTE pInfoBuffer = new BYTE[dwInfoBufferLength+2];
ZeroMemory(pInfoBuffer, dwInfoBufferLength);
BOOL bRet = TRUE;
while (!HttpQueryInfo(hRequest, HTTP_QUERY_RAW_HEADERS_CRLF, pInfoBuffer, &dwInfoBufferLength, NULL)) {
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
delete[] pInfoBuffer;
pInfoBuffer = new BYTE[dwInfoBufferLength+2];
ZeroMemory(pInfoBuffer, dwInfoBufferLength);
}
else {
delete[] pInfoBuffer;
return FALSE;
}
}
pInfoBuffer[dwInfoBufferLength] = '\0';
pInfoBuffer[dwInfoBufferLength+1] = '\0';
//分割字符串把头放到返回的map中
std::vector<std::wstring> vecHeaders = Split((PWCHAR)pInfoBuffer, L"\r\n");
delete[] pInfoBuffer;
for (std::vector<std::wstring>::iterator itIndex = vecHeaders.begin();
itIndex != vecHeaders.end(); itIndex++)
{
if (std::wstring::npos != itIndex->find(L":")) {
std::vector<std::wstring> vecItem = Split(*itIndex, L":");
if (vecItem.size() > 1) {
mapOutputHeaders.insert(std::make_pair(Trim(vecItem[0]), Trim(vecItem[1])));
}
}
}
//5.获取返回状态
//HTTP_QUERY_STATUS_CODE
dwInfoBufferLength = sizeof(dwRetCode);
if (!HttpQueryInfo(hRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwRetCode, &dwInfoBufferLength, NULL)) {
dwRetCode = 0;
}
/* lpRetData = nullptr;
dwRetSize = 0;*/
//6.获取数据
DWORD dwBytesAvailable = 0;
while (InternetQueryDataAvailable(hRequest, &dwBytesAvailable, 0, 0)
&& dwBytesAvailable > 0)
{
if (lpRetData) {
LPBYTE lpBuffer = new BYTE[dwBytesAvailable + dwRetSize];
CopyMemory(lpBuffer, lpRetData, dwRetSize);
delete[] lpRetData;
lpRetData = lpBuffer;
}
else {
lpRetData = new BYTE[dwBytesAvailable];
}
if (!InternetReadFile(hRequest, lpRetData + dwRetSize,
dwBytesAvailable, &dwBytesAvailable))
{
break;
}
dwRetSize += dwBytesAvailable;
dwBytesAvailable = 0;
}
return TRUE;
}
int main(int argc, char* argv[])
{
std::wstring strUrl = L"https://www.baidu.com";
std::map<std::wstring, std::wstring> mapInputHeaders;
std::map<std::wstring, std::wstring> mapOutputHeaders;
mapInputHeaders.insert(std::make_pair(L"test-header", L"test"));
DWORD dwRetCode;
LPBYTE lpRetBuffer;
DWORD dwRetSize;
SendRequest(strUrl, L"GET", nullptr, 0, mapInputHeaders,
dwRetCode, mapOutputHeaders, lpRetBuffer, dwRetSize
);
wprintf(L"%d\n", dwRetCode);
for (std::map<std::wstring, std::wstring>::iterator itIndx = mapOutputHeaders.begin();
itIndx != mapOutputHeaders.end(); itIndx++)
{
wprintf(L"%s:%s\n\n", itIndx->first.c_str(), itIndx->second.c_str());
}
printf("%s\n",lpRetBuffer);
return 0;
}
搬了下面文章部分代码:
https://www.likecs.com/show-985928.html
https://www.cnblogs.com/demon90s/p/15612975.html
