我想根据SSL证书的指纹拦截,检查和(如果需要)拒绝AJAX请求。我使用QNetworkAccessManager::createRequest(...)
函数发出请求。当我使用QWebFrame::load(...)
时,一切正常。甚至在请求中加载的内容(如.css或.js文件)也会发出信号。不幸的是,没有AJAX-Requests会发出任何信号。我知道信号在MyNetworkAccessManager::createRequest(...)
函数中连接到相同的插槽(用于"普通"以及AJAX请求)。
QNetworkReply *reply = QNetworkAccessManager::createRequest(op, req, outgoingData);
connect(reply, SIGNAL(readyRead()), this, SLOT(handleStarted()));
connect(reply, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(handleSslErrors(const QList<QSslError> &)));
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(handleNetworkError()));
为什么AJAX请求如此不同?我在哪里可以访问它们?
答案 0 :(得分:2)
据我所知,AJAX请求会在QNetworkAccessManager上发出完成的信号。您需要连接到QWebPage实例上的QNetworkAccessManager实例:
QWebPage *page = ui->webView->page();
QNetworkAccessManager *nam = page->networkAccessManager();
connect(nam, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
QFile file;
file.setFileName(":/js/jquery-2.1.1.min.js"); // jQuery is loaded as a resource
file.open(QIODevice::ReadOnly);
QString jQuery = file.readAll();
file.close();
ui->webView->load(QUrl("about:blank"));
QWebFrame *frame = m_page->mainFrame();
frame->evaluateJavaScript(jQuery); // load jQuery
// check that jQuery is loaded
frame->evaluateJavaScript("$(document).ready(function() { alert('jQuery loaded!'); });");
// do an AJAX GET
frame->evaluateJavaScript("$.ajax({"
"url: 'http://www.json-generator.com/api/json/get/cqkXBAEoQy?indent=2',"
"method: 'GET',"
"dataType: 'json'"
"}).done(function (data) {"
"for (var i = 0; i < data.length; i++) {"
"alert(data[i].name);"
"}"
"}).error(function (data) { alert('AJAX error'); });");
然后你可以监视replyFinished插槽中的回复,如下所示:
void MainWindow::replyFinished(QNetworkReply *reply)
{
QByteArray bytes = reply->readAll();
QString str = QString::fromUtf8(bytes.data(), bytes.size());
QString replyUrl = reply->url().toString();
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
qDebug() << statusCode;
qDebug() << replyUrl;
qDebug() << str;
}
我注意到当您对QNetworkReply执行任何操作时,jQuery AJAX的完成承诺似乎没有执行,但您可以看到请求实际上已在调试控制台中完成。
请参阅我的GitHub存储库以试用上述代码:https://github.com/pcmantinker/QtWebkitAJAX
就阻止基于SSL证书的连接而言,您必须继承QNetworkAccessManager并覆盖QNetworkAccessManager :: createRequest。这样的事情可以奏效:
QNetworkReply *CustomQNetworkAccessManager::createRequest(Operation op, const QNetworkRequest& request, QIODevice* outgoingData)
{
QNetworkRequest req(request);
QNetworkReply *reply = QNetworkAccessManager::createRequest(op, req, outgoingData);
QSslConfiguration *sslConfig = reply->sslConfiguration();
QList<QSslCertificate> sslCaCerts = sslConfig->caCertificates();
// do something with sslCaCerts
return reply;
}