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


当前回答

有什么方法可以简单地用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;
}

其他回答

你可以使用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;
}

你可以使用ACE这样做:

#include "ace/SOCK_Connector.h"

int main(int argc, ACE_TCHAR* argv[])
{
    //HTTP Request Header
    char* szRequest = "GET /video/nice.mp4 HTTP/1.1\r\nHost: example.com\r\n\r\n"; 
    int ilen = strlen(szRequest);

    //our buffer
    char output[16*1024];

    ACE_INET_Addr server (80, "example.com");
    ACE_SOCK_Stream peer;
    ACE_SOCK_Connector connector;
    int ires = connector.connect(peer, server);
    int sum = 0;
    peer.send(szRequest, ilen);
    while (true)
    {
        ACE_Time_Value timeout = ACE_Time_Value(15);
        int rc = peer.recv_n(output, 16*1024, &timeout);
        if (rc == -1)
        {
            break;
        }
        sum += rc;
    }
    peer.close();
    printf("Bytes transffered: %d",sum);

    return 0;
}

MS的CppRest SDK是我刚刚发现的,大约半小时后,我的第一个简单的web服务调用工作。相比之下,在这里提到的其他地方,我甚至无法安装任何东西,我不得不说,这是相当令人印象深刻的

https://github.com/microsoft/cpprestsdk

向下滚动,点击文档,然后点击入门教程,你将有一个简单的应用程序运行在任何时间。

libCURL是一个非常好的选择。根据你需要做什么,教程应该告诉你你想要什么,特别是简单的操作。但是,基本上,你可以这样做只是为了查看页面的源代码:

CURL* c;
c = curl_easy_init();
curl_easy_setopt( c, CURL_URL, "www.google.com" );
curl_easy_perform( c );
curl_easy_cleanup( c );

我相信这将导致结果被打印到标准输出。如果您想要处理它——我假设您是这样做的——您需要设置CURL_WRITEFUNCTION。上面链接的curl教程中介绍了所有这些内容。

2020年更新:我有一个新的答案来取代这个已经存在了8年的答案:https://stackoverflow.com/a/61177330/278976

在Linux上,我尝试了cppp -netlib、libcurl、curlpp、urdl、boost::asio,并考虑过Qt(但基于许可证拒绝了它)。所有这些都不是不完整的,有草率的界面,有糟糕的文档,没有维护或不支持https。

然后,在https://stackoverflow.com/a/1012577/278976的建议下,我尝试了POCO。哇,我真希望几年前就能看到。下面是一个使用POCO进行HTTP GET请求的示例:

https://stackoverflow.com/a/26026828/2817595

POCO是免费的、开源的(boost许可证)。不,我和这家公司没有任何关系;我真的很喜欢他们的界面。干得好,伙计们(和姑娘们)。

https://pocoproject.org/download.html

希望这能帮助到某人…我花了三天时间把所有这些库都试了一遍。