目录

基本理论

博主例子


基本理论

首先要理解缓存是如何被创建的:

浏览器首先先本地缓存发起创建请求,如果命中则返回数据给浏览器;

如果没有命中,就向代理服务器发起缓存,如果命中代理服务器会发给浏览器以及本地缓存;

如果没命中,则向资源服务器发起创建请求,然后资源服务器再给代理缓存,本地缓存,浏览器数据;

如果要实现这样的功能:

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_H

main.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实现)相关推荐

  1. git commit 遇到 “#modified: xxx/xxx (modified content)”问题的解决

    git commit 遇到 "#modified: xxx/xxx (modified content)"问题的解决 1.出现这样现象的原因 主要是因为xxx/xxx目录下有隐藏的 ...

  2. git status 遇到 “#modified: xxx/xxx (modified content)”问题的解决

    git status 时遇到  "#modified: xxx/xxx (modified content)"  想不要这些修改 但是 git restore 和 git chec ...

  3. Modified Polygon (Allow modified: No), (Allow shelved: No)/修改的多边形(允许修改:否)(允许搁置:否)

    AD软件规则检查时报错 解决方法 BUG解决了

  4. java304是什么错误_304 Not Modified 的意思 (Web的Cache问题)

    最近在观察咱网站Web的Cache问题,又进一步理解了 HTTP 中的 304 又有了一些了解. 304 的标准解释是:Not Modified 客户端有缓冲的文档并发出了一个条件性的请求(一般是提供 ...

  5. HTTP 304: Not Modified

    HTTP 304: Not Modified :Not Modified客户端有缓冲的文档并发出了一个条件性的请求(一般是提供if-Modified-Since头表示客户只想比指定日期更新的文档).服 ...

  6. YOLO v4它来了:接棒者出现,速度效果双提升

    来源:机器之心 本文约2188字,建议阅读7分钟. 本文介绍YOLO 的官方 Github 账号更新了 YOLO v4 的 arXiv 链接与开源代码链接,迅速引起了 CV 社区的关注. 两个月前,Y ...

  7. 收藏 | 一文总结70篇论文,帮你透彻理解神经网络的剪枝算法

    来源:DeepHub IMBA本文约9500字,建议阅读10+分钟 本文为你详细介绍神经网络剪枝结构.剪枝标准和剪枝方法. 无论是在计算机视觉.自然语言处理还是图像生成方面,深度神经网络目前表现出来的 ...

  8. 计算机程序的思维逻辑 (38) - 剖析ArrayList

    本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>(马俊昌著),由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买:京东自营链接 ...

  9. SharePoint2010 内容类型剖析

    SharePoint 2010 在上一版本的基础上进一步发展了内容类型对象.本系列作为一个专题,试图对其进行一个深入的剖析.方便大家在自己的自定义解决方案中对其进行定制. 内容类型的定义 ShareP ...

最新文章

  1. Python笔记——基本数据结构:列表、元组及字典
  2. 1104: 求因子和(函数专题)
  3. 常用的前端跨域的几种方式
  4. arXiv 注册流程介绍——详细图解
  5. P2P 网络核心技术:Gossip 协议
  6. python—多进程的消息队列
  7. spring 视频教程
  8. dell主板恢复出厂设置_戴尔恢复出厂设置【搞定办法】
  9. 电脑如设置路由器WiFi外加无线桥接一个副路由器
  10. python alpha通道_python – 使用matplotlib和alpha通道组合图片和绘图
  11. 问题 F: 求一个3*3矩阵对角线元素之和
  12. 特种浓缩分离:生物农药超滤分离提纯过滤技术
  13. android 屏幕没反应了,手机屏幕失灵了怎么办?安卓手机屏幕失灵解决方法
  14. Lucene 开发手册
  15. 小米电视如何安装第三方软件观看有线电视?看我如何操作
  16. Web(servlet) 应用程序将其发布在 Web AppServer 服务器(war包)
  17. 32位、64位与Java开发研究分析
  18. 【每日随笔】毕业论文答辩 ② ( 问答环节注意点 | 答辩陈述以及问题回答流程 )
  19. FreeCAD-0.19源码编译教程
  20. 汽车级三相无传感器、无刷直流(BLDC)电机控制器A4962

热门文章

  1. mysql导出(导入)数据库window平台
  2. 如何学习HTML语言
  3. 主机路由在计算机中的应用
  4. BAT老程序员分享:Linux C/C++ 开发程序员的黄金方向和学习路线!
  5. 世界是你们的,也是我们的,但终究是他们的!致程序员
  6. 我用大屏模板做年中可视化报告,惊艳了在场的同事和领导
  7. html5 字母索引,jQuery建立一个按字母顺序排列的友好页面索引(兼容IE6/7/8)
  8. matlab 图像语义分割,笔记︱图像语义分割(FCN、CRF、MRF)、论文延伸(Pixel Objectness、)...
  9. 本周开课 | 第 17 期高级转录组分析和R数据可视化火热报名中!!!
  10. Cell子刊:盗梦空间成真,科学家成功进入他人梦境,并与之“交流对话”