有什么方法可以简单地用c++发出HTTP请求吗?具体来说,我想下载一个页面(一个API)的内容,并检查内容,看看它是否包含1或0。是否也可以将内容下载到字符串中?


当前回答

现在正在开发一种更新的、不太成熟的卷曲包装器,称为c++ Requests。下面是一个简单的GET请求:

#include <iostream>
#include <cpr.h>

int main(int argc, char** argv) {
    auto response = cpr::Get(cpr::Url{"http://httpbin.org/get"});
    std::cout << response.text << std::endl;
}

它支持各种各样的HTTP动词和curl选项。这里有更多的使用文档。

免责声明:我是这个库的维护者。

其他回答

注意,这并不需要libcurl, Windows.h,或WinSock!没有编译库,没有项目配置,等等。我有这段代码在Windows 10上的Visual Studio 2017 c++中工作:

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

#include <urlmon.h>
#include <sstream>

using namespace std;

...

IStream* stream;
//Also works with https URL's - unsure about the extent of SSL support though.
HRESULT result = URLOpenBlockingStream(0, "http://google.com", &stream, 0, 0);
if (result != 0)
{
    return 1;
}
char buffer[100];
unsigned long bytesRead;
stringstream ss;
stream->Read(buffer, 100, &bytesRead);
while (bytesRead > 0U)
{
    ss.write(buffer, (long long)bytesRead);
    stream->Read(buffer, 100, &bytesRead);
}
stream->Release();
string resultString = ss.str();

我只是想出了如何做到这一点,因为我想要一个简单的API访问脚本,像libcurl这样的库给我带来了各种各样的问题(即使我遵循了说明……),而WinSock只是太低级和复杂了。

我不太确定所有的IStream读取代码(特别是while条件-请随意纠正/改进),但嘿,它工作,麻烦!(这对我来说是有意义的,因为我使用了一个阻塞(同步)调用,这是很好的,bytesRead将始终是> 0U,直到流(ISequentialStream?)完成读取,但谁知道呢。)

请参见:URL名称和异步可插协议参考

你可以使用embeddedRest库。它是一个轻量级的头文件库。所以很容易将它包含到你的项目中,它不需要编译,因为里面没有。cpp文件。

从自述文件中请求示例。Md from repo:

#include "UrlRequest.hpp"

//...

UrlRequest request;
request.host("api.vk.com");
const auto countryId = 1;
const auto count = 1000;
request.uri("/method/database.getCities",{
    { "lang", "ru" },
    { "country_id", countryId },
    { "count", count },
    { "need_all", "1" },
});
request.addHeader("Content-Type: application/json");
auto response = std::move(request.perform());
if (response.statusCode() == 200) {
  cout << "status code = " << response.statusCode() << ", body = *" << response.body() << "*" << endl;
}else{
  cout << "status code = " << response.statusCode() << ", description = " << response.statusDescription() << endl;
}

一般来说,我会推荐一些跨平台的工具,比如cURL、POCO或Qt。:

#include <atlbase.h>
#include <msxml6.h>
#include <comutil.h> // _bstr_t

HRESULT hr;
CComPtr<IXMLHTTPRequest> request;

hr = request.CoCreateInstance(CLSID_XMLHTTP60);
hr = request->open(
    _bstr_t("GET"),
    _bstr_t("https://www.google.com/images/srpr/logo11w.png"),
    _variant_t(VARIANT_FALSE),
    _variant_t(),
    _variant_t());
hr = request->send(_variant_t());

// get status - 200 if succuss
long status;
hr = request->get_status(&status);

// load image data (if url points to an image)
VARIANT responseVariant;
hr = request->get_responseStream(&responseVariant);
IStream* stream = (IStream*)responseVariant.punkVal;
CImage *image = new CImage();
image->Load(stream);
stream->Release();

有什么方法可以简单地用c++发出HTTP请求吗?具体来说,我想下载一个页面(一个API)的内容,并检查内容,看看它是否包含1或0。是否也可以将内容下载到字符串中?

首先……我知道这个问题已经有12年了。然而。没有一个答案给出的例子是“简单的”,不需要构建一些外部库

下面是我能想到的检索和打印网页内容的最简单的解决方案。

关于下面示例中使用的函数的一些文档

// wininet lib : https://learn.microsoft.com/en-us/windows/win32/api/wininet/ // wininet->internetopena(); https://learn.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-internetopena // wininet->intenetopenurla(); https://learn.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-internetopenurla // wininet->internetreadfile(); https://learn.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-internetreadfile // wininet->internetclosehandle(); https://learn.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-internetclosehandle

#include <iostream>

#include <WinSock2.h>
#include <wininet.h>
#pragma comment(lib, "wininet.lib")

int main()
{
    //  ESTABLISH SOME LOOSE VARIABLES
    const int size = 4096;
    char buf[size];
    DWORD length;

    //  ESTABLISH CONNECTION TO THE INTERNET
    HINTERNET internet = InternetOpenA("Mozilla/5.0", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, NULL);
    if (!internet)
        ExitProcess(EXIT_FAILURE);  //  Failed to establish connection to internet, Exit

    //  ATTEMPT TO CONNECT TO WEBSITE "google.com"
    HINTERNET response = InternetOpenUrlA(internet, "http://www.google.com", NULL, NULL, NULL, NULL);
    if (!response) {
        //  CONNECTION TO "google.com" FAILED
        InternetCloseHandle(internet);  //  Close handle to internet
        ExitProcess(EXIT_FAILURE);
    }

    //  READ CONTENTS OF WEBPAGE IN HTML FORMAT
    if (!InternetReadFile(response, buf, size, &length)) {     
        //  FAILED TO READ CONTENTS OF WEBPAGE
        //  Close handles and Exit
        InternetCloseHandle(response);                      //  Close handle to response
        InternetCloseHandle(internet);                      //  Close handle to internet
        ExitProcess(EXIT_FAILURE);
    }
    
    //  CLOSE HANDLES AND OUTPUT CONTENTS OF WEBPAGE
    InternetCloseHandle(response);                      //  Close handle to response
    InternetCloseHandle(internet);                      //  Close handle to internet
    std::cout << buf << std::endl;
    return 0;
}

cesanta的猫鼬库似乎也支持这一点:https://github.com/cesanta/mongoose/blob/6.17/examples/http_client/http_client.c