HTTP之Last-Modified、Etage、If-Modified-Since理论与实践(C++ Qt实现)
目錄
?
?
基本理論
博主例子
?
基本理論
首先要理解緩存是如何被創建的:
瀏覽器首先先本地緩存發起創建請求,如果命中則返回數據給瀏覽器;
如果沒有命中,就向代理服務器發起緩存,如果命中代理服務器會發給瀏覽器以及本地緩存;
如果沒命中,則向資源服務器發起創建請求,然后資源服務器再給代理緩存,本地緩存,瀏覽器數據;
?
如果要實現這樣的功能:
1. 瀏覽器本地有緩存,但每次還要向服務器發起請求,看看資源是不是更新了;
2. 如果更新了服務器發送新資源給瀏覽器,如果沒更新就叫瀏覽器讀取緩存;
?
要使用HTTP實現上面的功能,要具備以下的知識點:
1.? 服務器響應頭中的no-cahce為每次發起請求都要在服務器那邊驗證下,如果服務器能讓瀏覽器使用本地緩存,才能使用。no-store為本地和代理服務器都不能存儲緩存;每次都要拿新的。
2. 服務器響應頭中有兩根驗證頭,一個是Last-Modified和一個Etag。
3. Last-Modified為上次修改時間,配合請求頭中的If-Modified或If-Unmodified-Since使用,對比上傳修改時間以驗證資源是否需要更新。
4. Etag為數字簽名,配合If-Match或If-Non-Match使用,對比資源的簽名判斷是否使用緩存。
?
博主例子
服務器運行截圖如下:
這個是回正常的200的HTTP數據包;
這樣是回304讀取本地緩存的包,
先把他調到正常會HTTP包;
瀏覽器數據如下:
這里看看其大小:
當變為回304時:
發現大小改變了:
但文本內容還是沒變:
看看數據包詳細信息:‘
程序結構如下:
源碼如下:
widget.h
#ifndef WIDGET_H #define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE class QTcpServer; class QTcpSocket; QT_END_NAMESPACEnamespace Ui { class Widget; }class Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent = 0);~Widget();protected slots:void newConnectionSlot80();void errorStringSlot80();void sendMsg80();void btnClicked();private:Ui::Widget *ui;QTcpServer *m_tcpServer80;QTcpSocket *m_tcpSocket80;};#endif // WIDGET_Hmain.cpp
#include "widget.h" #include <QApplication>int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); }widget.cpp
#include "widget.h" #include "ui_widget.h" #include <QTcpServer> #include <QDebug> #include <QTcpSocket>Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget) {ui->setupUi(this);m_tcpServer80 = new QTcpServer(this);m_tcpServer80->listen(QHostAddress::Any, 80);connect(m_tcpServer80, SIGNAL(newConnection()), this, SLOT(newConnectionSlot80()));connect(m_tcpServer80, SIGNAL(acceptError(QAbstractSocket::SocketError)), this, SLOT(errorStringSlot80()));connect(ui->pushButton, SIGNAL(clicked(bool)), this, SLOT(btnClicked())); }Widget::~Widget() {delete ui;m_tcpServer80->close(); }void Widget::newConnectionSlot80() {qDebug() << "newConnectionSlot80() called";m_tcpSocket80 = m_tcpServer80->nextPendingConnection();sendMsg80();//connect(m_tcpSocket80, SIGNAL(readyRead()), this, SLOT(sendMsg80()));//connect(m_tcpSocket80, SIGNAL(connected()), this, SLOT(sendMsg80())); }void Widget::errorStringSlot80() {qDebug() << m_tcpServer80->errorString(); }void Widget::sendMsg80() {QString contentStr;QString str;if(ui->pushButton->text() == "正常回HTTP包"){contentStr = "<html>""<head>""<title>""Socket 80""</title>""</head>""<body>""<h1>Socket 80</h1>""</body>""</html>";//send msgstr = "HTTP/1.1 200 OK\r\n";str.append("Server:nginx\r\n");str.append("Content-Type:text/html\r\n");str.append("Access-Control-Allow-Origin: *\r\n");str.append("Connection:keep-alive\r\n");str.append("Cache-Control: max-age=200000\r\n");str.append("Last-Modified: 777777\r\n");str.append("Etage: 888888\r\n");str.append(QString("Content-Length:%1\r\n\r\n").arg(contentStr.size()));str.append(contentStr);//qDebug() << str;}else{str = "HTTP/1.1 304 OK\r\n";str.append("Server:nginx\r\n");str.append("Content-Type:text/html\r\n");str.append("Access-Control-Allow-Origin: *\r\n");str.append("Connection:keep-alive\r\n");str.append("Cache-Control: max-age=200000, no-cache\r\n");str.append("Last-Modified: 777777\r\n");str.append("Etage: 888888\r\n");str.append(QString("Content-Length:%1\r\n\r\n").arg(contentStr.size()));}m_tcpSocket80->write(str.toStdString().c_str()); }void Widget::btnClicked() {if(ui->pushButton->text() == "正常回HTTP包"){ui->pushButton->setText("回304包");}else{ui->pushButton->setText("正常回HTTP包");} }?
源碼打包下載地址:
https://github.com/fengfanchen/Qt/tree/master/HTTPLast-Modified
總結
以上是生活随笔為你收集整理的HTTP之Last-Modified、Etage、If-Modified-Since理论与实践(C++ Qt实现)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Git笔记-Connection res
- 下一篇: CORS跨域限制以及预请求验证(C++