关于Qt解析Http和Https链接的文件信息

介绍

记录下之前Qt做的解析Http和Https的文件信息的过程。

思路

Qt这边已经提供了Network给我们解析,所以不是特殊的话,没必要再去找其他库来解决。主要思路是发送请求后,等待触发解析结束的信号,然后接收这个信号去解析里面的内容。
同时要获取文件名的话,会有多种情况要去解析。
1、网页里面已经写好了Content-Disposition,那么可以直接解析出这个字段来获取filename。
2、没有Content-Disposition,那么就去获取它的basename。
3、还需要考虑到多级跳转情况,这个时候要跳转多次才能获取到Disposition或者真正目标地址的basename。
4、下面代码只供思路参考,用的时候不建议直接copy。

#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply>
//....省略....
protected:
    QNetworkAccessManager m_manager; // 发送请求和接收应答
    QNetworkRequest m_request; // 保存准备发送的请求
    QNetworkReply *m_reply; // 接收到的应答
    QUrl m_url; // 要解析的地址
    QString m_strFileName; // 存放解析出来的文件名
    QString m_strFileSize; // 存放解析出来的文件的大小
     /**
     * @brief Parse2FileName 解析Url,该操作是异步
     * @param url 要解析的地址
     */
    void ParseFileInfo(std::string url);

private slots:
    void OnGetHeaders(); 
void XXXX::ParseFileInfo(std::string url)
{
    m_strFileName = "";
    m_strFileSize = "";
    m_url = QUrl::fromUserInput(QString(url.c_str()));
    m_request.setUrl(m_url);
    m_reply = m_manager.head(m_request); // 解析头
    connect(m_reply, &QNetworkReply::finished, this, &ParseUrl::OnGetHeaders); // 等待结束
}


void XXXX::OnGetHeaders()
{
    if(m_reply->hasRawHeader("Content-Disposition"))
    {
        QString strFileName = m_reply->rawHeader("Content-Disposition");
        int idx = strFileName.indexOf(QStringLiteral("filename="));
        if(idx >= 0) //找到filename字段
        {
            strFileName = strFileName.replace('"', ""); //filename=后面有双引号,应该全部删除
            strFileName = strFileName.mid(idx + 9);
            m_strFileName = strFileName;
        }
    }
    else //如果没有Content-Disposition,则用QUrl获取basename
    {
        m_url = m_reply->url();
        if(!m_url.isEmpty())
        {
            m_strFileName = m_url.fileName();
        }
    }

    if(m_reply->hasRawHeader("Content-Length"))
    {
        QString strFileSize = m_reply->rawHeader("Content-Length");
        m_strFileSize = strFileSize;
    }
    else
    {
        m_strFileSize = "0";
    }
}

上面这样,就能获取到没有跳转的http的文件信息了。但是如果出现多级跳转的话,是无法正确拿到的。这边有两个做法:
1、如果解析出来的header里面有location,那么就套娃解析,直到没有,然后再去取文件名。
2、初始化request时候,设置request属性,让request自己帮我们跳转。

m_request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); 

采用这两种方法,碰到跳转的链接时候,都能正确拿到URL。

注意点

但是如果去解析https的话,很多人此时会报SSL的错。一般情况下是Qt安装目录下少了对应的DLL。
这时候根据你的客户端(32或者64位),去安装对应位数的OpenSSL,然后去OpenSSL的目录下,将目录下的库移到Qt对应编译器的下面,这步骤可以百度,因为Qt版本不同和编译器不同处理方法也不同,就不转载了。

qDebug() << QSslSocket::supportsSsl() << QSslSocket::sslLibraryBuildVersionString() << QSslSocket::sslLibraryVersionString();

可以事先打印这句话,如果是false那就是不支持https的,如果是true,那么解析https一般就没问题了。当然这是我自己遇到的情况,不是适合所有人。

不对的地方或者有更好的方法欢迎评论指正,也希望这部分代码能帮助到需要的人。
在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值