2013-02-11 33 views
5

Tôi có một người xem web và chỉ muốn nó có thể truy cập vào các ứng dụng web của chúng tôi, để đạt được điều này, tôi đã đặt một tiêu đề php mà tôi tìm trong Ứng dụng Qt của mình. Điều này làm việc tốt nhưng với một ngoại lệ và đó là với 301 mã trạng thái chuyển vĩnh viễn. Các trình duyệt hiện đại sẽ tự động chuyển hướng bạn nhưng đặt "/" ở cuối yêu cầu http.Chuyển hướng QNetworkReply và 301

Khi URL vào ứng dụng web của chúng tôi được nhập, hiện tại cần dấu gạch chéo để có thể phát hiện tiêu đề nhưng tôi cũng muốn có tiêu đề đó ngay cả khi chúng không đặt dấu gạch chéo.

Đây là phương pháp hiện tại của tôi để lấy tiêu đề:

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; 
    } 

Để khắc phục tình trạng của chạm 301 đầu tiên tôi gửi hai yêu cầu mạng, Người đầu tiên chạm URL đã nhập và kiểm tra 301 nếu có một mã trạng thái 301 nó nhận được url được đề xuất thông qua phương thức reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); và trả về URL đó nếu không có mã trạng thái, sau đó nó trả về URL trước mà người dùng đã nhập và sau đó gửi một yêu cầu mạng khác để kiểm tra tiêu đề.

yêu cầu đầu tiên tôi gửi ra để kiểm tra mã trạng thái:

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; 
     } 

    } 
} 

câu chuyện dài ngắn, Tôi gửi hai yêu cầu mạng, 1) Để kiểm tra 301 2) Để kiểm tra các tiêu đề ứng dụng của chúng tôi.

Có cách nào để thực hiện việc này trong một yêu cầu không? Tôi có thiếu một phương pháp sẽ tự động thực hiện chuyển hướng này không?

Trân

Nathan

Trả lời

9

Rõ ràng không có.

Có một mục HOWTO chính thức về http://developer.nokia.com/community/wiki/Handling_an_HTTP_redirect_with_QNetworkAccessManager (link chết, không may)

Extraction từ liên kết ở trên:

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

tưởng có thể không phải là một cách nhưng không chắc chắn nếu tôi nhớ da diết cái gì đó ở đâu đó, nhờ sự giải thích rõ ràng @kfunk :) – Kal

+1

liên kết đến HOWTO chính thức bị phá vỡ :( –

+0

@ DavidSánchez: Cập nhật các bình luận Thật không may là nội dung wiki đã không được di chuyển trước khi xóa nó: ( – kfunk

14

Đây là một chút nhưng hỗ trợ tự động chuyển hướng chút cũ chỉ được thêm vào Qt 5.6. Kiểm tra điều này ra QNetworkRequest::FollowRedirectsAttribute (http://doc.qt.io/qt-5/qnetworkrequest.html).

+1

Bạn có ý nghĩa gì với tôi nó là mới. Cảm ơn bạn đã đề cập đến điều này, bạn đã lưu ** của tôi, tôi sẽ cập nhật từ 5.5 đến 5.6 để làm việc này. –

Các vấn đề liên quan