有什么方法可以简单地用c++发出HTTP请求吗?具体来说,我想下载一个页面(一个API)的内容,并检查内容,看看它是否包含1或0。是否也可以将内容下载到字符串中?
当前回答
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
希望这能帮助到某人…我花了三天时间把所有这些库都试了一遍。
其他回答
虽然有点晚了。你可能更喜欢https://github.com/Taymindis/backcurl。
它允许你在移动c++开发上进行http调用。适合手机游戏开发
bcl::init(); // init when using
bcl::execute<std::string>([&](bcl::Request *req) {
bcl::setOpts(req, CURLOPT_URL , "http://www.google.com",
CURLOPT_FOLLOWLOCATION, 1L,
CURLOPT_WRITEFUNCTION, &bcl::writeContentCallback,
CURLOPT_WRITEDATA, req->dataPtr,
CURLOPT_USERAGENT, "libcurl-agent/1.0",
CURLOPT_RANGE, "0-200000"
);
}, [&](bcl::Response * resp) {
std::string ret = std::string(resp->getBody<std::string>()->c_str());
printf("Sync === %s\n", ret.c_str());
});
bcl::cleanUp(); // clean up when no more using
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教程中介绍了所有这些内容。
一般来说,我会推荐一些跨平台的工具,比如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++没有提供任何直接实现它的方法。这完全取决于你拥有什么样的平台和库。
在最坏的情况下,您可以使用boost::asio库来建立TCP连接,发送HTTP报头(RFC 2616),并直接解析响应。查看您的应用程序需求,这很简单。
下面是一些(相对)简单的c++ 11代码,使用libCURL将URL的内容下载到std::vector<char>:
http_download.hh
# pragma once
#include <string>
#include <vector>
std::vector<char> download(std::string url, long* responseCode = nullptr);
http_download.cc
#include "http_download.hh"
#include <curl/curl.h>
#include <sstream>
#include <stdexcept>
using namespace std;
size_t callback(void* contents, size_t size, size_t nmemb, void* user)
{
auto chunk = reinterpret_cast<char*>(contents);
auto buffer = reinterpret_cast<vector<char>*>(user);
size_t priorSize = buffer->size();
size_t sizeIncrease = size * nmemb;
buffer->resize(priorSize + sizeIncrease);
std::copy(chunk, chunk + sizeIncrease, buffer->data() + priorSize);
return sizeIncrease;
}
vector<char> download(string url, long* responseCode)
{
vector<char> data;
curl_global_init(CURL_GLOBAL_ALL);
CURL* handle = curl_easy_init();
curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, callback);
curl_easy_setopt(handle, CURLOPT_WRITEDATA, &data);
curl_easy_setopt(handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
CURLcode result = curl_easy_perform(handle);
if (responseCode != nullptr)
curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, responseCode);
curl_easy_cleanup(handle);
curl_global_cleanup();
if (result != CURLE_OK)
{
stringstream err;
err << "Error downloading from URL \"" << url << "\": " << curl_easy_strerror(result);
throw runtime_error(err.str());
}
return data;
}