热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

深入探索HTTP协议的学习与实践

在初次访问某个网站时,由于本地没有缓存,服务器会返回一个200状态码的响应,并在响应头中设置Etag和Last-Modified等缓存控制字段。这些字段用于后续请求时验证资源是否已更新,从而提高页面加载速度和减少带宽消耗。本文将深入探讨HTTP缓存机制及其在实际应用中的优化策略,帮助读者更好地理解和运用HTTP协议。

关于HTTP缓存

第一次进入一个网站时,本地无缓存,response成功返回200

服务器在Response Header里,设置了Etag和Last-Modify,如下图;
img

Etag字段将资源唯一性的标识,如果资源有更新,Etag值也将变化;

Last-Modify表明了在服务器端最后发生改变的时间;

浏览器保存这个Etag值和Last-Modify,以便于下次请求的时候使用;

img

刷新后,发送的Request Header如下:

img

其中If-None-Match字段就是向服务器端询问第一次的Etag值是否更新,两次Etag相同,说明资源未发生根本改变

If-Modified-Since向服务器询问在这个时间发生改变了吗;

img

img

最终发回响应,Etag和Last-Modify无变化,所以最终返回304,比第一次的ResponseHeader相比,还多了两个字段Cache-Control: max-ageExpires

这两个属性就是为了告诉浏览器,不必再来询问服务器资源过没过期,允许浏览器在一个时间段内继续使用本地缓存;

max-age属于HTTP1.1 ,Expires属于HTTP1.0,如果max-age和Expires同时存在,Expires则被Cache-Control的max-age覆盖。

另外返回的ResponseHeader还有Via字段,说明经过了很多代理服务器,这说明我们要的资源可能是放在了CDN上的;

还有个字段Vary,它可对缓存进行控制,它告诉代理服务器,返回和Accept-Encoding字段相同的缓存资源,而不是从源服务器端;

禁用HTTP缓存

no-store不缓存任何内容

no-cache先向服务器验证缓存

两种加密方法:

共享密钥加密(对称加密):加密解密用同一密钥,当客户端发送数据时,用密钥加密,同时也要把密钥发给服务器端。这样造成的问题是密钥容易被中间攻击者获取,也能解密内容;

公开密钥加密(非对称加密):加密用公开密钥加密,解密用私有密钥解密。其中公开密钥任何人都能获取,私有密钥不公开。当客户端发送数据时,用公钥加密,服务器端再用自己的私钥解密;

HTTPS是在HTTP和TCP之间,再填一层SSL,SSL的基本思想是用非对称加密来建立链接(握手阶段),用对称加密来传输数据(传输阶段)。这样做是因为非对称加密比对称加密复杂,计算量大,所以只在建立连接阶段来传送对称加密的密钥;

具体建立连接步骤如下:

  • 1.客户端发送ClientHello报文,告诉服务器端自己支持的SSL版本等信息;
  • 2.服务器端返回ServerHello,告诉浏览器自己支持的SSL版本等信息;
  • 3.服务器发送证书给浏览器,包含了公钥;
  • 4.服务器发送SeverHelloDone,完成握手协商;
  • 5.客户端产生随机的密码,作为对称加密的密钥,并用第三步的公钥加密;
  • 6.以后的信息传输都使用第五步的密钥加密;

HTTP长连接

在HTTP1.1中默认开启长连接 connection: keep-alive,这样是为了复用TCP,频繁的HTTP请求会造成频繁的TCP建立。

使用 connection: keep-alive后,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会立即关闭,之后的Ajax请求、静态文件请求,会继续使用这一条已经建立的连接,但是Keep-Alive不会永久保持连接,它有一个保持时间,超过保持时间仍会断开。

Comet推送

虽然HTTP1.1的TCP连接有一个保持时间,超过保持时间会断开,但是我们可以不时地向这条连接发送数据,这样这个连接就一直不会断开。所以可以用HTTP长连接来做一个不使用客户端轮询的Comet推送。

采用Node编写的服务器端代码:


if (request.url == '/ct' && request.method == "POST") {var body="";request.on("data", function(chunk) {body += chunk;});request.on("end", function() {response.writeHead(200, {'Content-Type': "text/event-stream"});var json={'type':'connect'}json=JSON.stringify(json)response.write(json);console.log(body)response.id=body;clients.push(response); //clients数组保存Response});request.connection.on("end",function () { //断开时删除对应的Responseclients.splice(clients.indexOf(response),1);response.end();})
}setInterval(function() {clients.forEach(function (client) { //每10000ms发送一次数据来保持HTTP长连接不断开var json={'type':'event'}json=JSON.stringify(json)client.write(json);})
}, 10000);



推荐阅读
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • PHP 5.2.5 安装与配置指南
    本文详细介绍了 PHP 5.2.5 的安装和配置步骤,帮助开发者解决常见的环境配置问题,特别是上传图片时遇到的错误。通过本教程,您可以顺利搭建并优化 PHP 运行环境。 ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 深入解析Spring Cloud Ribbon负载均衡机制
    本文详细介绍了Spring Cloud中的Ribbon组件如何实现服务调用的负载均衡。通过分析其工作原理、源码结构及配置方式,帮助读者理解Ribbon在分布式系统中的重要作用。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 本文深入探讨了Linux系统中网卡绑定(bonding)的七种工作模式。网卡绑定技术通过将多个物理网卡组合成一个逻辑网卡,实现网络冗余、带宽聚合和负载均衡,在生产环境中广泛应用。文章详细介绍了每种模式的特点、适用场景及配置方法。 ... [详细]
  • 扫描线三巨头 hdu1928hdu 1255  hdu 1542 [POJ 1151]
    学习链接:http:blog.csdn.netlwt36articledetails48908031学习扫描线主要学习的是一种扫描的思想,后期可以求解很 ... [详细]
  • 本文介绍了如何使用 Spring Boot DevTools 实现应用程序在开发过程中自动重启。这一特性显著提高了开发效率,特别是在集成开发环境(IDE)中工作时,能够提供快速的反馈循环。默认情况下,DevTools 会监控类路径上的文件变化,并根据需要触发应用重启。 ... [详细]
  • 本文探讨了Hive中内部表和外部表的区别及其在HDFS上的路径映射,详细解释了两者的创建、加载及删除操作,并提供了查看表详细信息的方法。通过对比这两种表类型,帮助读者理解如何更好地管理和保护数据。 ... [详细]
  • Python自动化处理:从Word文档提取内容并生成带水印的PDF
    本文介绍如何利用Python实现从特定网站下载Word文档,去除水印并添加自定义水印,最终将文档转换为PDF格式。该方法适用于批量处理和自动化需求。 ... [详细]
  • MQTT技术周报:硬件连接与协议解析
    本周开发笔记重点介绍了在新项目中使用MQTT协议进行硬件连接的技术细节,涵盖其特性、原理及实现步骤。 ... [详细]
  • 如何在窗口右下角添加调整大小的手柄
    本文探讨了如何在传统MFC/Win32 API编程中实现类似C# WinForms中的SizeGrip功能,即在窗口的右下角显示一个用于调整窗口大小的手柄。我们将介绍具体的实现方法和相关API。 ... [详细]
author-avatar
woshishuia小姐
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有