簡體   English   中英

vk api on boost c++ 無法正常工作

[英]vk api on boost c++ doesn't work correctly

我寫了一些代碼,應該發送 GET 請求並獲得響應。
它適用於 ip-api.com 並返回 json 文件。
但是對於 api.vk.com 它返回 html :

 <html>
    <head><title>301 Moved Permanently</title></head>
    <body>
        <center><h1>301 Moved Permanently</h1></center>
        <hr><center>kittenx</center>
    </body>
</html>

最有趣的是程序返回了正確的鏈接,打開后將執行所需的 GET 請求。

主.cpp:

#include <iostream>

#include "client.hpp"
#include "json.hpp"

std::string get_token(const std::string &);

int main()
{
    std::string token = get_token("data/token1");    
    

    std::string query = "https://api.vk.com/method/groups.getMembers?access_token=" + token + "&v=5.13&group_id=klubauto";


    std::cout << query << "\n\n\n";

    Client client(url);
    client.send_request(query);
    std::string response = client.get_response();


    std::cout << response << std::endl;


    return 0;
}

客戶端.hpp:

#pragma once

#include <string>

#include <boost/beast.hpp>
#include <boost/asio/connect.hpp>
#include <boost/asio/ip/tcp.hpp>


namespace http = boost::beast::http;



class Client
{
public:

    Client();
    Client(const std::string &api);
    ~Client();

    void send_request(const std::string &arguments);
    std::string get_response();
    
    
private:
    boost::asio::io_context io;
    boost::asio::ip::tcp::resolver resolver;
    boost::asio::ip::tcp::socket socket;

    std::string url;

};

客戶端.cpp

#include "client.hpp"

/*
*   Constructors
*/
Client::Client() : url("google.com"), resolver(io), socket(io)
{
    boost::asio::connect(socket, resolver.resolve(url, "80"));
}

Client::Client(const std::string &api) : url(api), resolver(io), socket(io)
{
    boost::asio::connect(socket, resolver.resolve(url, "80"));
}

/*
*   Destructor
*/
Client::~Client()
{
    socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
}


/*
*   Send request
*/
void Client::send_request(const std::string &arguments)
{
    http::request<http::string_body> req(http::verb::get, arguments, 11);

    req.set(http::field::host, url);
    req.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING);

    http::write(socket, req);
}


/*
*   Get response
*/
std::string Client::get_response()
{

    std::string response;
    {
        boost::beast::flat_buffer buffer;
        http::response<http::dynamic_body> res;
        http::read(socket, buffer, res);
        response = boost::beast::buffers_to_string(res.body().data());
    }

    return response;
}

我想在響應變量中接收 json 文件,請告訴我如何實現?

就像我評論的那樣,這就是 HTTP 的工作方式:服務器可以重定向到更好/新的位置。

我認為主要原因是因為您的連接不是 HTTPS,而這正是端點所需要的。 所以,先解決這個問題。

接下來,您的查詢包括基礎 URL,這是另一個錯誤。

現場演示

#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include <boost/beast.hpp>
#include <string>
namespace http = boost::beast::http;
namespace ssl  = boost::asio::ssl;
using boost::asio::ip::tcp;

class Client {
  public:
    Client(const std::string& host = "google.com") : _host(host) {
        _ctx.set_default_verify_paths();
        connect(_socket.lowest_layer(),
                tcp::resolver{_io}.resolve(_host, "https"));
        _socket.handshake(ssl::stream_base::client);
    }

    void send_request(const std::string& query)
    {
        http::request<http::string_body> req(http::verb::get, query, 11);
        req.set(http::field::host, _host);
        req.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING);
        http::write(_socket, req);
    }

    std::string get_response() {
        http::response<http::string_body> res;
        boost::beast::flat_buffer         buffer;
        http::read(_socket, buffer, res);
        return std::move(res.body());
    }

  private:
    boost::asio::io_context  _io;
    ssl::context             _ctx{ssl::context::sslv23_client};
    ssl::stream<tcp::socket> _socket{_io, _ctx};
    std::string              _host;
};

#include <iostream>
#include <boost/json.hpp>
#include <boost/json/src.hpp> // for COLIRU header-only
namespace json = boost::json;

std::string get_token(const std::string&) { return ""; }

int main()
{
    Client client("api.vk.com");
    client.send_request("/method/groups.getMembers?access_token=" +
                        get_token("data/token1") + "&v=5.13&group_id=klubauto");

    std::cout << json::parse(client.get_response()) << std::endl;
}

Coliru 不允許公共網絡訪問:

terminate called after throwing an instance of 'boost::wrapexcept<boost::system::system_error>'
  what():  resolve: Service not found

但在我的機器上它正確地說:

{"error":{"error_code":5,"error_msg":"User authorization failed: no access_token passed.","request_params":[{"key":"v","value":"5.13"},{"key":"group_id","value":"klubauto"},{"key":"method","value":"groups.getMembers"},{"key":"oauth","value":"1"}]}}

請注意,我在此過程中包含了很多簡化。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM