一、关于HTTP的协议版本

HTTP的全称是Hyper Text Transfer Protocol的缩写,即超级文本传输协议。HTTP协议用于定义浏览器与服务器之间交换数据的过程以及数据本身的格式。

HTTP是无状态协议,对于事务处理没有记录能力。因此后续处理如果需要前面的信息,则它必须重传,这会导致每次连接传送的数据量增大.

HTTP目前主要有三个版本:1.0、1.1、2.0。

http1.0的交互过程如下图所示:

  • 缺陷:浏览器与服务器只保持短暂的连接,浏览器的每次请求都需要与服务器建立一个TCP连接(TCP连接的新建成本很高,因为需要客户端和服务器三次握手),服务器完成请求处理后立即断开TCP连接,服务器不跟踪每个客户也不记录过去的请求;

  • 解决方案:

    • 添加头信息——非标准的Connection字段Connection: keep-alive

http1.1:

  • 改进点:

  1. 持久连接

  • 引入了持久连接,即TCP连接默认不关闭,可以被多个请求复用,不用声明Connection: keep-alive(对于同一个域名,大多数浏览器允许同时建立6个持久连接)

管道机制

  • 即在同一个TCP连接里面,客户端可以同时发送多个请求。

分块传输编码

  • 即服务端没产生一块数据,就发送一块,采用”流模式”而取代”缓存模式”。

新增请求方式

  • PUT:请求服务器存储一个资源;

  • DELETE:请求服务器删除标识的资源;

  • OPTIONS:请求查询服务器的性能,或者查询与资源相关的选项和需求;

  • TRACE:请求服务器回送收到的请求信息,主要用于测试或诊断;

  • CONNECT:保留将来使用

  • 缺点:

    • 虽然允许复用TCP连接,但是同一个TCP连接里面,所有的数据通信是按次序进行的。服务器只有处理完一个请求,才会接着处理下一个请求。如果前面的处理特别慢,后面就会有许多请求排队等着。这将导致“队头堵塞”

    • 避免方式:一是减少请求数,二是同时多开持久连接

HTTP/2.0

HTTP 2.0协议是在1.x基础上的升级而不是重写,1.x协议的方法,状态及api在2.0协议里是一样的。2.0协议重点是对终端用户的感知延迟、网络及服务器资源的使用等性能的优化。

  • 特点:

  1. 采用二进制格式而非文本格式;

  2. 完全多路复用,而非有序并阻塞的、只需一个连接即可实现并行;

  3. 使用报头压缩,降低开销

  4. 服务器推送

1. 二进制协议

  • HTTP/1.1 版的头信息肯定是文本(ASCII编码),数据体可以是文本,也可以是二进制。HTTP/2 则是一个彻底的二进制协议,头信息和数据体都是二进制,并且统称为”帧”:头信息帧和数据帧。

  • 二进制协议解析起来更高效、“线上”更紧凑,更重要的是错误更少。

  • http2.0之所以能够突破http1.X标准的性能限制,改进传输性能,实现低延迟和高吞吐量,就是因为其新增了二进制分帧层。

  • 在二进制分帧层上,http2.0会将所有传输信息分割为更小的消息和帧,并对它们采用二进制格式的编码将其封装,新增的二进制分帧层同时也能够保证http的各种动词,方法,首部都不受影响,兼容上一代http标准。其中,http1.X中的首部信息header封装到Headers帧中,而request body将被封装到Data帧中。如下图所示:

2. 完全多路复用

  • HTTP/2 复用TCP连接,在一个连接里,客户端和浏览器都可以同时发送多个请求或回应,而且不用按照顺序一一对应,这样就避免了”队头堵塞”。

3. 报头压缩

  • HTTP 协议是没有状态,导致每次请求都必须附上所有信息。所以,请求的很多头字段都是重复的,比如Cookie,一样的内容每次请求都必须附带,这会浪费很多带宽,也影响速度。

  • 对于相同的头部,不必再通过请求发送,只需发送一次;

  • HTTP/2 对这一点做了优化,引入了头信息压缩机制;

  • 一方面,头信息使用gzip或compress压缩后再发送;

  • 另一方面,客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,产生一个索引号,之后就不发送同样字段了,只需发送索引号。

4. 服务器推送

  • HTTP/2 允许服务器未经请求,主动向客户端发送资源;

  • 通过推送那些服务器任务客户端将会需要的内容到客户端的缓存中,避免往返的延迟。

二、HTTP的请求方式

HTTP主要有8种请求方式,如下所示:

在这8种HTTP请求方式中,GET和POST是最常用的。网页上的form表单的默认提交方式是GET(在form表单的method属性不设置时)。

在实际的开发中,我们通常都会使用POST方式发送请求,而不是GET,原因有两个:

(1)POST传输数据大小无限制

(2)POST比GET请求方法更安全:GET请求的参数会在URL地址栏铭文显示,而POST请求方式传递的参数隐藏在实体内容中,用户看不到。

、HTTP的请求消息与响应消息

HTTP的请求消息和响应消息是相对应的,都包含三大部分:

HTTP消息除了请求头和响应头外,还有一些通用头字段,如下所示:

三、会话技术

在Web开发中,服务器跟踪用户信息的技术成为会话技术。

会话技术有两种实现:

(1)Cookie:将会话的过程数据保存到用户浏览器上。

(2)Session: 将会话数据保存到服务器端。

Cookie技术

Cookie通过将会话过程的数据保存到用户的浏览器上,使浏览器和服务器可以更好地进行数据交互。

我们可以形象的将Cookie理解成我们在商场办的会员卡。卡上记录了个人信息、消费额度和积分额度等。以后每次去商场,商场根据会员就能很快了解到顾客的会员信息。

在Cookie模式下,当用户通过浏览器访问Web服务器时,web服务器会给客户发送一些信息,这些信息都保存在Cookie中。这样,当浏览器再次访问服务器时,都会在请求头中将Cookie发送给服务器,Web服务器端可以分辨出当前请求是由哪个用户发出的,方便服务器对浏览器做出正确的响应,如下图所示:

为了封装Cookie信息,前端开发语言必要要有对应的方式。传统Servlet API会通过javax.servlet.http.Cookie类来实现。里面包含生成Cookie信息和提取Cookie信息的方法。由于现在Servlet已经不再被大量使用,因此我们不展开说明。

JavaScript Cookie的详细内容,可以看这个链接:

https://github.com/js-cookie/js-cookie

需要注意的是,无论浏览器是否支持Cookie,用户第一次访问程序时,由于服务器不知道客户浏览器是否支持Cookie,在第一次响应的页面中都会对URL地址进行重写。如果浏览器支持,那么后续的访问中都会使用Cookie的请求投资端将Session的标识号传递给服务器。由此,服务器判断浏览器支持Cookie,后续不再对URL进行重写。否则后续每个请求的URL都需要进行重写。

Session技术

Cookie的技术可以将用户的信息保存在各自的浏览器中,并且可以在多次请求下实现数据的共享。但如果传递的信息比较多,使用Cookie技术会增大服务器端的程序处理难度。这时,可以使用Session实现,它是一种将会话数据保存到服务器上的技术。

如果形象点说,Session技术就好比医院发给病人的就医卡。就医卡上只有卡号,没有其他信息,病人去看病时,主要出示就医卡,医院就可以根据卡号查到病历档案的过程。

当浏览器访问Web服务器时,Servlet容器(还以此举例)会创建一个Session对象和ID属性。Session对象相当于病例档案,ID就相当于就医卡号。客户端后续访问服务器时,只要将标识号传递给服务器,服务器就能根据请求是哪个客户发的,从而选择与之对应的Session对象为其服务。

需要注意的是:由于客户端要接受、记录和发送Session对象的ID,而Session是借助Cookie技术来传递ID属性的。

Session保存用户信息如下图所示:

为了方便理解,我们通过两端代码分别验证Cookie和Session的功能。

需求1:设计一个类,使用Cookie技术实现显示用户上次访问时间的功能。

package cn.itcast.chapter06.cookie.example;

import java.io.IOException;

import java.util.Date;

import javax.servlet.ServletException;

import javax.servlet.http.Cookie;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public class LastAccessServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {

response.setContentType("text/html;charset=utf-8");

/*

* 设定一个 cookie 的name : lastAccessTime

* 读取客户端发送cookie 获得用户上次的访问时间显示*/

String lastAccessTime = null;

// 获取所有的cookie,并将这些cookie存放在数组中

Cookie[] cookies = request.getCookies();

for (int i = 0; cookies != null && i < cookies.length; i++) {

if ("lastAccess".equals(cookies[i].getName())) {

// 如果cookie的名称为lastAccess,则获取该cookie的值

lastAccessTime = cookies[i].getValue();

break;

}

}

// 判断是否存在名称为lastAccess的cookie

if (lastAccessTime == null) {

response.getWriter().print("您是首次访问本站!!!");

} else {

response.getWriter().print("您上次的访问时间"+lastAccessTime);

}

// 创建cookie,将当前时间作为cookie的值发送给客户端

Cookie cookie = new Cookie("lastAccess",new Date().toLocaleString());

cookie.setMaxAge(60*60);//保存1小时

//访问chapter06下资源时回送cookie

cookie.setPath("/chapter06");

// 发送 cookie

response.addCookie(cookie);

}

}

需求2::设计一个类,使用Session技术实现购物车功能。

public class PurchaseServlet extends HttpServlet {

public void doGet(HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException {

// 获得用户购买的商品

String id = req.getParameter("id");

if (id == null) {

// 如果id为null,重定向到ListBookServlet页面

String url = "/chapter06/ListBookServlet";

resp.sendRedirect(url);

return;

}

Book book = BookDB.getBook(id);

// 创建或者获得用户的Session对象

HttpSession session = req.getSession();

// 从Session对象中获得用户的购物车

List cart = (List)

session.getAttribute("cart");

if (cart == null) {

// 首次购买,为用户创建一个购物车(List集合模拟购物车)

cart = new ArrayList();

// 将购物城存入Session对象

session.setAttribute("cart", cart);

}

// 将商品放入购物车

cart.add(book);

// 创建Cookie存放Session的标识号

Cookie cookie = new Cookie("JSESSIONID", session.getId());

cookie.setMaxAge(60 * 30);

cookie.setPath("/chapter06");

resp.addCookie(cookie);

// 重定向到购物车页面

String url = "/chapter06/CartServlet";

resp.sendRedirect(url);

}

}

参考:

《Jva Web程序开发入门》-清华大学出版社

https://zhuanlan.zhihu.com/p/89471776

https://zhuanlan.zhihu.com/p/89471776

http访问不到服务器_HTTP及会话技术解析:大魏Java记4相关推荐

  1. php如何保存服务器会话,如何用PHP在服务器上创建会话?

    在SAC的回答中,如果您只想让单个媒体播放器使用认证系统,您还需要实现认证系统,就像Netflix所做的那样.Netflix生成一个存储在注册表中的密钥,用于标识您的计算机并使用该密钥访问Netfli ...

  2. web服务器是如何维护,我们如何维护Web客户端和Web服务器之间的会话?

    以下是维护Web客户端和Web服务器之间的会话的一些选项- 饼干 Web服务器可以将唯一的会话ID作为cookie分配给每个Web客户端,对于来自客户端的后续请求,可以使用接收到的cookie来识别它 ...

  3. 共享会话怎么设置没访问自动断开_谁总结的JavaWeb会话技术了?太全面了...

    本文同名博客老炮说Java:https://www.laopaojava.com/,每天更新Spring/SpringMvc/SpringBoot/实战项目等文章资料 顺便再给大家推荐一套Spring ...

  4. 内网主机通过公网域名解析访问内网服务器,存在什么问题,如何解决?

    发生问题:数据通信无法实现 根本原因:DNS域名解析解析出来是公网地址,就是内网用户向外网用户发送DNS查询,外网DNS会给内网用户回复,如果防火墙上面加了DNS参数,防火墙就会监控DNS回包,如果发 ...

  5. 路由器端口映射,远程桌面连接--端口映射+花生壳=让人访问你个人服务器或WEB站点...

    [图]路由器端口映射,远程桌面连接--端口映射+花生壳=让人访问你个人服务器或WEB站点 2010-03-16   关键字:路由器端口映射,内网端口映射,porttunnel,端口映射,远程桌面,修改 ...

  6. java 调用 sas_通过JAVA、VB访问SAS IOM服务器

    欢迎进入Java社区论坛,与200万技术人员互动交流 >>进入 通过IOM("Integrated Object Model" )服务器,没有必要使SAS安装在本地系统 ...

  7. Android模拟器(包括Genymotion)访问本机服务器

    废话不说了,直接上我遇到的坑: Android模拟器访问本机服务器(比如:Tomcat),要这么写:http://10.0.2.2:port/dir 重点说genymotion 一定记住要这么写:ht ...

  8. 使用叶神模拟器无法访问本机服务器的问题(报错:java.net.ConnectException: failed to connect to /127.0.0.1 (port 5000) )

    最近打算用夜神模拟器来和本机服务器做一些信息交互的功能,但是服务器搭建好了,用叶神模拟器却无法访问.折腾了大半天才发现原来是模拟器的问题. 具体过程如下: 搭建好服务器后,在本机上访问"ht ...

  9. 可以访问本地mysql服务器的命令是_在用户访问本地MySQL服务器时,访问命令可以省略“–h localhost”。...

    [单选题]1.男性,46岁,胃溃疡伴瘢痕性幽门梗阻.行毕Ⅱ式胃大部切除术后第8天,突然发生上腹部剧痛,呕吐频繁,每次量少,不含胆汁,呕吐后症状不缓解.体检:上腹部偏右有压痛.首先考虑并发了 [判断题] ...

最新文章

  1. 数据结构与算法:选择排序
  2. CSS 实现打字效果
  3. python1000个常用代码-比较了1000多个Python开源项目,精选出这34个
  4. Java平台无关性——跨平台
  5. python打印二进制内容,Python字节不打印二进制
  6. android 控件描边取消重叠
  7. 程序员的一个好习惯,你有几个?
  8. goahead如何使用cgi服务_QQ如何设置使用代理服务器?
  9. #3771. Triple(生成函数 + 容斥)
  10. Android 页面多状态布局管理
  11. request.path 值危险
  12. 1000道Python题库系列分享26(12道Pandas编程题)
  13. 桌面环境选择_Fedora 30 正式版发布:引入 Deepin 桌面环境(DDE)
  14. [Linux] day03——REHL部署
  15. python中unicode编码表_python中的unicode编码
  16. 思聪吃热狗(双人版)
  17. 上海海洋大学计算机专硕调剂,2019年上海海洋大学硕士研究生调剂政策和规则...
  18. 便利店牵手京东到家,多元零售矩阵走向成熟化
  19. [SAE]免费服务器:新浪云服务器SAE的注册与使用
  20. 用iframe的方式 解决 window.open() 不能打开多个窗口的问题

热门文章

  1. 计算机在职英语,计算机在职研究生英语教学存在的不足
  2. 动态库、静态库、运行时库、引入库之间的区别
  3. Win10+vs2013+Caffe静态库配置自己的工程
  4. MFC模块的动态链接库DLL以及静态链接库LIB编译后的调用
  5. NotImplementedError: Cannot convert a symbolic Tensor (lstm/strided_slice:0) to a numpy array.
  6. 数据结构与算法17-表插入排序
  7. Python基础——正则2(0503)
  8. Windows Phone笔记索引(总)
  9. Python(十)之GUI编程
  10. defer与async的认识