【问题标题】:Libcurl get response "415 Unsupported Media Type" But working well using Curl.exeLibcurl 得到响应“415 Unsupported Media Type”但使用 Curl.exe 运行良好
【发布时间】:2021-02-20 10:16:07
【问题描述】:

我不确定我做错了什么,但是在 curl 中使用该命令时不会发生错误。即使已经声明了curl_easy_setopt(curl, CURLOPT_HEADER, "Content-Type: application/json");,我的类型仍然会更改为Content-Type: application/x-www-form-urlencoded 这是我的代码:

    curl_easy_setopt(curl, CURLOPT_URL, "https://zone1:50000/user/login");
    curl_easy_setopt(curl, CURLOPT_POST, 1);
    curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "cookies.txt");
    const std::string raw_json = R"json({ "username": "admin", "password": "password123"})json";

        Json::CharReaderBuilder builder {};
        auto reader = std::unique_ptr<Json::CharReader>( builder.newCharReader() );
        Json::Value root {};
        std::string errors {};
        const auto is_parsed = reader->parse( raw_json.c_str(),
                                              raw_json.c_str() + raw_json.length(),
                                              &root,
                                              &errors );
        if ( !is_parsed )
        {
            qDebug() << "ERROR: Could not parse! " << errors.c_str();
        }
        Json::FastWriter fastWriter;
        std::string output = fastWriter.write(root);
        qDebug() << "Parsed JSON:" << output.c_str();
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS,output.c_str());
    curl_easy_setopt(curl, CURLOPT_HEADER, "Origin: https://zone1:50000");
    curl_easy_setopt(curl, CURLOPT_ENCODING, "Accept-Encoding: gzip, deflate, br");
    curl_easy_setopt(curl, CURLOPT_HEADER, "Accept-Language: en-US,en;q=0.9");
    curl_easy_setopt(curl, CURLOPT_HEADER, "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36");
    curl_easy_setopt(curl, CURLOPT_HEADER, "Content-Type: application/json");
    curl_easy_setopt(curl, CURLOPT_HEADER, "Accept: application/json, text/plain, */*");
    curl_easy_setopt(curl, CURLOPT_HEADER, "Referer: https://zone1:50000/login");
    curl_easy_setopt(curl, CURLOPT_HEADER, "Connection: keep-alive");
    res = curl_easy_getinfo(curl, CURLINFO_COOKIELIST, cookies);
    res = curl_easy_perform(curl);

成功的curl命令:

curl --cookie cookie.txt -k -g "https://zone1:50000/user/login" -H "Origin: https://zone1:50000" -H "Accept-Encoding: gzip, deflate, br" -H "Accept-Language: en-US,en;q=0.9" -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36" -H "Content-Type: application/json" -H "Accept: application/json, text/plain, */*" -H "Referer: https://zone1:50000/login" -H "Cookie: JSESSIONID=Fn1" -H "Connection: keep-alive" --data-binary "{\"username\":\"admin\",\"password\":\"password\"}"

我收到的回复:

  • 找到主机 zone1 的捆绑包:0x11ce588 [串行]

  • 即使我们想,也不能多路复用!

  • 重用现有连接! (#0) 与主机 zone1

  • 连接到 zone1 (10.1.233.120) 端口 50000 (#0) *> POST /user/login HTTP/1.1 主机:zone1:50000 接受:/ 接受编码:接受编码:gzip、deflate、br 内容长度:44 内容类型:application/x-www-form-urlencoded

  • 上传完全发送:44 个字节中的 44 个

  • 将捆绑包标记为不支持多用途

【问题讨论】:

    标签: c++ curl libcurl


    【解决方案1】:

    你设置的标题都错了,CURLOPT_HTTPHEADER 的标题列表不是 char*,它是一种特殊的列表,试试

    struct curl_slist *list = NULL;
    list = curl_slist_append(list, "Accept-Language: en-US,en;q=0.9");
    list = curl_slist_append(list, "Content-Type: application/json");
    list = curl_slist_append(list, "Accept: application/json, text/plain, */*");
    list = curl_slist_append(list, "Referer: https://zone1:50000/login");
    list = curl_slist_append(list, "Connection: keep-alive");
    curl_easy_setopt(curl, CURLOPT_HEADER, list);
    (...)
    curl_slist_free_all(list);
    (...)
    

    也不要使用 CURLOPT_HEADER 来设置User-Agent,因为如果将来你执行多个请求,或者如果你使用 CURLOPT_FOLLOWLOCATION,curl 会“忘记”用户代理,而是使用 CURLOPT_USERAGENT,所以 curl 不会算了:

    curl_easy_setopt(curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36");
    

    【讨论】:

    • 仍然有同样的结果
    【解决方案2】:

    我通过添加解决了我的问题

    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
    char* jsonObj = "{ \"username\" : \"admin\" , \"password\" : \"password123\" }";
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS,jsonObj );
    

    感谢@hanshenrik 指出创建标题列表。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-18
      • 2022-10-04
      • 2017-11-16
      • 2021-07-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多