2013-02-11 375 views
5

我有一个webviewer,只希望它只能够访问我们的webapps,为此我已经放置了一个php头,我在我的Qt应用程序中寻找。这工作正常,但有一个例外,那是301永久移动的状态代码。现代浏览器会自动重定向您,但会在http请求的末尾添加“/”。QNetworkReply和301重定向

当输入我们的网络应用程序的URL时,它当前需要尾部斜线能够检测标题,但是我希望它也能够在该标题处得到,即使它们没有放置尾部斜线。

这是我目前的检索标题方法:

QNetworkAccessManager *manager = new QNetworkAccessManager(this); 
    QNetworkRequest request; 
    request.setUrl(url); 
    connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(onFinished(QNetworkReply*))); 

    request.setRawHeader("User-Agent", "CytoViewer 1.0"); 
    request.setHeader(QNetworkRequest::ContentTypeHeader,"application/CytoViewer"); 
    QNetworkReply *reply = manager->get(request); 
    reply->ignoreSslErrors(); 
    QEventLoop loop; 

    connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); 
    loop.exec(); 
    qDebug() << "QLoop reply all: " << reply->readAll(); 
    qDebug() << "QLoop: " << reply->rawHeader("Cyto-Study-Manager"); 
    if(reply->rawHeader("OurWebApp") == "1"){ 
     //Header exists?(QEventLoop finish) Set arg[1]"url 'Found prouct: product header'" 
     product = reply->rawHeader("Product"); 
     return true; 
    } else { 
     //Header doen't exist? Graceful error - not a valid PI product 
     return false; 
    } 

为了解决击中301首先我送两个网络请求的问题,第一个打网址进入,并检查了301,如果有一个301状态码,它通过reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();方法得到建议的URL,如果没有状态码,则返回该URL,否则它仅仅返回用户输入的前一个URL,然后发送另一个网络请求来检查标题。

我送出去检查状态码第一个请求:

QUrl MainWindow::networkRequest(QUrl checkUrl){ 
    qDebug() << "checkURL: " << checkUrl; 
    // 
    QNetworkAccessManager *manager = new QNetworkAccessManager(this); 
    QNetworkRequest request; 
    request.setUrl(checkUrl); 
    request.setRawHeader("User-Agent", "CytoViewer 1.0"); 
    request.setHeader(QNetworkRequest::ContentTypeHeader,"application/CytoViewer"); 
    QNetworkReply *reply = manager->get(request); 
    reply->ignoreSslErrors(); 
    QEventLoop checkLoop; 
    connect(reply, SIGNAL(finished()), &checkLoop, SLOT(quit())); 
    checkLoop.exec(); 
    //Check status code 
    if (reply->error() == QNetworkReply::NoError) { 
     int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); 
     if(statusCode == 301) { 
      QUrl redirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); 
      return redirectUrl; 
     }else { 
      return checkUrl; 
     } 

    } 
} 

长话短说,我送两个网络请求,1)要检查301 2)要检查我们的应用程序标题。

有没有办法在一个请求中做到这一点?我是否缺少自动执行此重定向的方法?

问候

弥敦道

回答

9

显然没有。

有上http://developer.nokia.com/community/wiki/Handling_an_HTTP_redirect_with_QNetworkAccessManager官方HOWTO条目(死链接,不幸)

提取从上面的链接:

void QNAMRedirect::replyFinished(QNetworkReply* reply) { 
    /* 
    * Reply is finished! 
    * We'll ask for the reply about the Redirection attribute 
    * http://doc.trolltech.com/qnetworkrequest.html#Attribute-enum 
    */ 
    QVariant possibleRedirectUrl = 
      reply->attribute(QNetworkRequest::RedirectionTargetAttribute); 

    /* We'll deduct if the redirection is valid in the redirectUrl function */ 
    _urlRedirectedTo = this->redirectUrl(possibleRedirectUrl.toUrl(), 
             _urlRedirectedTo); 

    /* If the URL is not empty, we're being redirected. */ 
    if(!_urlRedirectedTo.isEmpty()) { 
     QString text = QString("QNAMRedirect::replyFinished: Redirected to ") 
           .append(_urlRedirectedTo.toString()); 
     this->_textContainer->setText(text); 

     /* We'll do another request to the redirection url. */ 
     this->_qnam->get(QNetworkRequest(_urlRedirectedTo)); 
    } 
    else { 
     /* 
     * We weren't redirected anymore 
     * so we arrived to the final destination... 
     */ 
     QString text = QString("QNAMRedirect::replyFinished: Arrived to ") 
           .append(reply->url().toString()); 
     this->_textContainer->setText(text); 
     /* ...so this can be cleared. */ 
     _urlRedirectedTo.clear(); 
    } 
    /* Clean up. */ 
    reply->deleteLater(); 
} 

QUrl QNAMRedirect::redirectUrl(const QUrl& possibleRedirectUrl, 
           const QUrl& oldRedirectUrl) const { 
    QUrl redirectUrl; 
    /* 
    * Check if the URL is empty and 
    * that we aren't being fooled into a infinite redirect loop. 
    * We could also keep track of how many redirects we have been to 
    * and set a limit to it, but we'll leave that to you. 
    */ 
    if(!possibleRedirectUrl.isEmpty() && 
     possibleRedirectUrl != oldRedirectUrl) { 
     redirectUrl = possibleRedirectUrl; 
    } 
    return redirectUrl; 
} 
+0

想到有可能没有办法,但不知道我是否失去了某个地方的东西,感谢清除@kfunk :) – Kal 2013-02-11 10:11:39

+1

官方HOWTO的链接已损坏:( – 2015-11-24 08:17:55

+0

@DavidSánchez:更新了评论以反映这一点。不幸的是,维基内容在删除之前还没有被移动:( – kfunk 2016-01-03 18:14:41

14

这是一个有点老,但自动重定向的支持也刚刚加入的Qt 5.6。看看这个QNetworkRequest::FollowRedirectsAttributehttp://doc.qt.io/qt-5/qnetworkrequest.html)。

+1

你是什么意思旧?对我来说这是新的。谢谢你提到这个,你救了我一个**,我会从5.5更新到5.6为此工作。 – 2016-06-09 09:33:27