В Гугл Хром, когда в запросе к серверу возникает ошибка, Гугл Хром пытается новый запрос, см. LOG Wireshark:
Примечание: эта вторая попытка также происходит в Firefox и InternetExplorer.
Примечание. WebInspector отображается только в запросе, другими словами: обычные браузеры пробуют новые запросы несколько раз или в течение определенного времени.
Я разрабатываю полный браузер в QT
и понял, что если запрос не удается «QWebView» имеет такое же поведение, как Гугл Хром.
Как я могу переопределить QNetWorkRequest/QNetWorkAccessManager
работать как обычные браузеры?
Помоги мне, пожалуйста.
myWebPage *myWP = new myWebPage();
myWP->setForwardUnsupportedContent(true);
myWP->setNetworkAccessManager(m_network);
ui->myWebView->setPage(myWP);
if(q!=true) {
settings = QWebSettings::globalSettings();
settings->setAttribute(QWebSettings::OfflineWebApplicationCacheEnabled,true);
settings->setAttribute(QWebSettings::LocalContentCanAccessRemoteUrls,true);
settings->setAttribute(QWebSettings::OfflineStorageDatabaseEnabled,true);
settings->setAttribute(QWebSettings::LocalContentCanAccessFileUrls,true);
settings->setAttribute(QWebSettings::LocalStorageEnabled,true);
settings->setAttribute(QWebSettings::JavascriptCanOpenWindows,true);
settings->setAttribute(QWebSettings::JavascriptCanCloseWindows,true);
settings->setAttribute(QWebSettings::JavascriptEnabled,true);
settings->setAttribute(QWebSettings::PluginsEnabled,true);
settings->setAttribute(QWebSettings::JavaEnabled,false);//Disable java
settings->setAttribute(QWebSettings::DeveloperExtrasEnabled,true);
settings->setAttribute(QWebSettings::AutoLoadImages, true);settings->setAttribute(QWebSettings::DnsPrefetchEnabled, true);
settings->setAttribute(QWebSettings::LocalStorageDatabaseEnabled, true);
settings->setAttribute(QWebSettings::AcceleratedCompositingEnabled, true);
settings->setAttribute(QWebSettings::JavascriptCanAccessClipboard, false);
settings->setAttribute(QWebSettings::ScrollAnimatorEnabled, true);
settings->setAttribute(QWebSettings::PrintElementBackgrounds, false);
settings->setOfflineWebApplicationCachePath(QString(localStorage+"/appcache"));
settings->enablePersistentStorage(QString(localStorage+"/persistent"));
settings->setOfflineStoragePath(QString(localStorage+"/offlinestorage"));
settings->setLocalStoragePath(QString(localStorage+"/storage"));
settings->setIconDatabasePath(QString(localStorage+"/icons"));
settings->setMaximumPagesInCache(99999);
settings->setObjectCacheCapacities(0,99999,99999);
settings->setOfflineWebApplicationCacheQuota(5*1024*1024);
settings->setOfflineStorageDefaultQuota(5*1024*1024);
}
connect(ui->myWebView->page(), SIGNAL(downloadRequested(QNetworkRequest)), this, SLOT(Download(QNetworkRequest)));
connect(ui->myWebView->page(), SIGNAL(unsupportedContent(QNetworkReply*)), this, SLOT(unsupportedToDownload(QNetworkReply*)));
connect(ui->myWebView->page(), SIGNAL(printRequested(QWebFrame*)), this, SLOT(printFrame(QWebFrame*)));
Я решил проблему:
network.h
#ifndef NETWORK_H
#define NETWORK_H
#include <QNetworkAccessManager>
class netWork : public QNetworkAccessManager
{
Q_OBJECT
protected:
virtual QNetworkReply *createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData = 0);
public:
explicit netWork(QObject *parent = 0);
};
#endif // NETWORK_H
network.cpp
#include "network.h"#include <QNetworkReply>
#include <QNetworkRequest>
netWork::netWork(QObject *parent) :
QNetworkAccessManager(parent)
{
}
QNetworkReply * netWork::createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData){
if(request.rawHeader("x-fixed-req")=="1") {//prevent infinite loop
return QNetworkAccessManager::createRequest(op, request, outgoingData);
}
const QList<QByteArray>a = request.rawHeaderList();
int j = a.length();
int i=0;
QNetworkRequest req(request.url());
for(;i<j;++i){
req.setRawHeader(a[i], request.rawHeader(a[i]));
}
req.setRawHeader("x-fixed-req", "1");
QNetworkReply *p;
if(op==PostOperation || op==PutOperation) {
const QByteArray data = outgoingData->readAll();
if(op==PostOperation) {
p = this->post(req, data);
} else {
p = this->put(req, data);
}
} else if(op==DeleteOperation) {
p = this->deleteResource(req);
} else if(op==HeadOperation) {
p = this->head(req);
} else {
p = this->get(req);
}
return p;
}
MainWindow.cpp (или что-то)
#include "network.h";
bool firstExec = false;
QNetworkCookieJar *cookieJar;
QNetworkDiskCache *m_cache;
netWork *m_network = new netWork; //custom networkaccessmanager
...
if(firstExec==false){
firstExec = true;
cookieJar = new QNetworkCookieJar;
m_cache = new QNetworkDiskCache();
m_cache->setCacheDirectory( QString("c:\\data") );
m_network->setCache( m_cache );
m_network->setCookieJar( cookieJar );
}
[QWEBVIEW]->setNetworkAccessManager( m_network );
Примечание: чтобы использовать куки и кеш, используйте функции QNetworkAccessManager :: setCookieJar а также QNetworkAccessManager :: setCache
Других решений пока нет …