为什么80%的码农都做不了架构师?>>>   

#0 系列目录#

  • WEB请求处理
  • WEB请求处理一:浏览器请求发起处理
  • WEB请求处理二:Nginx请求反向代理
  • WEB请求处理三:Servlet容器请求处理
  • WEB请求处理四:Tomcat配置实践
  • WEB请求处理五:MVC框架请求处理

#1 HTTP报文# HTTP报文是面向文本的,报文中的每一个字段都是一些ASCII码串,各个字段的长度是不确定的。HTTP有两类报文:请求报文和响应报文。 ##1.1 HTTP请求报文解剖## ###1.1.1 请求报文结构### HTTP请求报文由3部分组成(请求行+请求头+请求体):

下面是一个实际的请求报文:

①为请求方法,GET和POST是最常见的HTTP方法,除此以外还包括DELETE、HEAD、OPTIONS、PUT、TRACE。不过,当前的大多数浏览器只支持GET和POST,Spring 3.0提供了一个HiddenHttpMethodFilter,允许你通过“_method”的表单参数指定这些特殊的HTTP方法(实际上还是通过POST提交表单)。服务端配置了HiddenHttpMethodFilter后,Spring会根据_method参数指定的值模拟出相应的HTTP方法,这样,就可以使用这些HTTP方法对处理方法进行映射了。

GET:最常见的一种请求方式,服务器将URL定位的资源放在响应报文的数据部分,回送给客户端。地址中”?”之后的部分就是通过GET发送的请求数据,各个数据之间用”&”符号隔开。显然,这种方式不适合传送私密数据。另外,由于不同的浏览器对地址的字符限制也有所不同,一般最多只能识别1024个字符,所以如果需要传送大量数据的时候,也不适合使用GET方式

POST:对于上面提到的不适合使用GET方式的情况,可以考虑使用POST方式,因为使用POST方法可以允许客户端给服务器提供信息较多。POST方法将请求参数封装在HTTP请求数据中,以名称/值的形式出现,可以传输大量数据,这样POST方式对传送的数据大小没有限制,而且也不会显示在URL中。

关于HTTP请求GET和POST的区别:

  1. GET提交:请求的数据会附在URL之后(就是把数据放置在HTTP协议头<request-line>中),以?分割URL和传输数据,多个参数用&连接。如果数据是英文字母/数字,原样发送,如果是空格,转换为+,如果是中文/其他字符,则直接把字符串用BASE64加密,得出如: %E4%BD%A0%E5%A5%BD,其中%XX中的XX为该符号以16进制表示的ASCII。   POST提交:把提交的数据放置在是HTTP的报文体<request-body>中。 因此,GET提交的数据会在地址栏中显示出来,而POST提交,地址栏不会改变
  2. 传输数据的大小: 首先声明,HTTP协议没有对传输的数据大小进行限制,HTTP协议规范也没有对URL长度进行限制。 而在实际开发中存在的限制主要有:  GET:特定浏览器和服务器对URL长度有限制,例如IE对URL长度的限制是2083字节(2K+35)。对于其他浏览器,如Netscape、FireFox等,理论上没有长度限制,其限制取决于操作系统的支持。 因此对于GET提交时,传输数据就会受到URL长度的限制。 POST:由于不是通过URL传值,理论上数据不受限。但实际各个WEB服务器会规定对post提交数据大小进行限制,Apache、IIS6都有各自的配置。  3. 安全性: POST的安全性要比GET的安全性高。注意:这里所说的安全性和上面GET提到的“安全”不是同个概念。上面“安全”的含义仅仅是不作数据修改,而这里安全的含义是真正的Security的含义,比如:通过GET提交数据,用户名和密码将明文出现在URL上,因为(1)登录页面有可能被浏览器缓存,(2)其他人查看浏览器的历史纪录,那么别人就可以拿到你的账号和密码了,

②为请求对应的URL地址,它和报文头的Host属性组成完整的请求URL。

③为协议名称及版本号

④为HTTP的报文头,报文头包含若干个属性,格式为“属性名:属性值”,服务端据此获取客户端的信息。

⑤为报文体,它将一个页面表单中的组件值通过param1=value1&param2=value2的键值对形式编码成一个格式化串,它承载多个请求参数的数据。不但报文体可以传递请求参数,请求URL也可以通过类似于“/chapter15/user.html?param1=value1&param2=value2”的方式传递请求参数。

**对照上面的请求报文,我们把它进一步分解,你可以看到一幅更详细的结构图: **

###1.1.2 HTTP请求报文头属性### 报文头属性是什么东西呢?我们不妨以一个小故事来说明吧。

快到中午了,张三丰不想去食堂吃饭,于是打电话叫外卖:老板,我要一份[鱼香肉丝],要12:30之前给我送过来哦,我在江湖湖公司研发部,叫张三丰。

这里,你要[鱼香肉丝]相当于HTTP报文体,而“12:30之前送过来”,你叫“张三丰”等信息就相当于HTTP的报文头。它们是一些附属信息,帮忙你和饭店老板顺利完成这次交易

请求HTTP报文和响应HTTP报文都拥有若干个报文关属性,它们是为协助客户端及服务端交易的一些附属信息。

  1. Accept:

请求报文可通过一个“Accept”报文头属性告诉服务端 客户端接受什么类型的响应。

如下报文头相当于告诉服务端,俺客户端能够接受的响应类型仅为纯文本数据啊,你丫别发其它什么图片啊,视频啊过来,那样我会歇菜的~~~:

Accept:text/plain

Accept属性的值可以为一个或多个MIME类型的值,关于MIME类型,大家请参考:http://en.wikipedia.org/wiki/MIME_type

  1. Cookie:

客户端的Cookie就是通过这个报文头属性传给服务端的哦!如下所示:

Cookie: $Version=1; Skin=new;jsessionid=5F4771183629C9834F8382E23BE13C4C

服务端是怎么知道客户端的多个请求是隶属于一个Session呢?注意到后台的那个jsessionid=5F4771183629C9834F8382E23BE13C4C木有?原来就是通过HTTP请求报文头的Cookie属性的jsessionid的值关联起来的!(当然也可以通过重写URL的方式将会话ID附带在每个URL的后面哦)。

  1. Referer:

表示这个请求是从哪个URL过来的,假如你通过google搜索出一个商家的广告页面,你对这个广告页面感兴趣,鼠标一点发送一个请求报文到商家的网站,这个请求报文的Referer报文头属性值就是http://www.google.com。

唐僧到了西天.
如来问:侬是不是从东土大唐来啊?
唐僧:厉害!你咋知道的!
如来:呵呵,我偷看了你的Referer...

很多貌似神奇的网页监控软件(如著名的 我要啦),只要在你的网页上放上一段JavaScript,就可以帮你监控流量,全国访问客户的分布情况等报表和图表,其原理就是通过这个Referer及其它一些HTTP报文头工作的。

  1. Cache-Control:

对缓存进行控制,如一个请求希望响应返回的内容在客户端要被缓存一年,或不希望被缓存就可以通过这个报文头达到目的。

如以下设置,相当于让服务端将对应请求返回的响应内容不要在客户端缓存:

Cache-Control: no-cache
``` 5. **User-Agent:**产生请求的浏览器类型。6. **Host:**请求的主机名,允许多个域名同处一个IP地址,即虚拟主机。###1.1.3 如何访问请求报文头###
由于请求报文头是客户端发过来的,服务端当然只能读取了,以下是HttpServletRequest一些用于读取请求报文头的API:

// 获取请求报文中的属性名称   java.util.Enumeration<java.lang.String>   getHeaderNames();      // 获取指定名称的报文头属性的值   java.lang.String getHeader(java.lang.String name);


由于一些请求报文头属性“太著名”了,因此HttpServletRequest为它们提供了VIP的API:

// 获取报文头中的Cookie(读取Cookie的报文头属性)  Cookie[]   getCookies() ;      // 获取客户端本地化信息(读取 Accept-Language 的报文头属性)   java.util.Locale    getLocale()       // 获取请求报文体的长度(读取Content-Length的报文头属性)   int getContentLength();

// 获取请求所关联的HttpSession,其内部的机理是通过读取请求报文头中Cookie属性的JSESSIONID的值, // 在服务端的一个会话Map中,根据这个JSESSIONID获取对应的HttpSession的对象 HttpSession getSession()


##1.2 HTTP响应报文解剖##
###1.2.1 响应报文结构###
HTTP的响应报文也由三部分组成(**响应行+响应头+响应体**): ![HTTP响应报文结构](http://upload-images.jianshu.io/upload_images/2062729-1a7bd8708dbc9390.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)以下是一个实际的HTTP响应报文: ![实际的HTTP响应报文](http://upload-images.jianshu.io/upload_images/2062729-b0d87f06a8ae130a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)①报文协议及版本; ②状态码及状态描述; ③响应报文头,也是由多个属性组成; ④响应报文体,即我们真正要的“干货”;###1.2.2 响应状态码###
和请求报文相比,响应报文多了一个“响应状态码”,它以“清晰明确”的语言告诉客户端本次请求的处理结果。**HTTP的响应状态码由5段组成:**
> 1xx 消息,**一般是告诉客户端,请求已经收到了,正在处理**,别急...。
>
> 2xx **处理成功**,一般表示:请求收悉、我明白你要的、请求已受理、已经处理完成等信息。
>
> 3xx **重定向到其它地方**。它让客户端再发起一个请求以完成整个处理。
>
> 4xx **处理发生错误,责任在客户端**,如客户端的请求一个不存在的资源,客户端未被授权,禁止访问等。
>
> 5xx **处理发生错误,责任在服务端**,如服务端抛出异常,路由出错,HTTP版本不支持等。**以下是几个常见的状态码:**
> **200 OK** 你最希望看到的,即处理成功!
>
> **301 永久重定向** Location响应首部的值仍为当前URL,因此为隐藏重定向;
>
> **302 临时重定向** 显式重定向, Location响应首部的值为新的URL。
>
> **303 See Other** redirect到其它的页面,目标的URL通过响应报文头的Location告诉你。
>
> **304 Not Modified** 告诉客户端,你请求的这个资源至你上次取得后,并没有更改,你直接用你本地的缓存吧,我很忙哦,你能不能少来烦我啊!
>
> **400 Bad Request** 客户端请求有语法错误,不能被服务器所理解。
>
> **401 Unauthorized** 请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用。
>
> **403 Forbidden** 服务器收到请求,但是拒绝提供服务。
>
> **404 Not Found** 你最不希望看到的,即找不到页面。如你在google上找到一个页面,点击这个链接返回404,表示这个页面已经被网站删除了,google那边的记录只是美好的回忆。
>
> **500 Internal Server Error** 看到这个错误,你就应该查查服务端的日志了,肯定抛出了一堆异常,别睡了,起来改BUG去吧!
>
> **503 Server Unavailable** 服务器当前不能处理客户端的请求,一段时间后可能恢复正常,举个例子:HTTP/1.1 200 OK(CRLF)。其它的状态码参见:[http://en.wikipedia.org/wiki/List_of_HTTP_status_codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)有些响应码,Web应用服务器会自动给生成。你可以通过HttpServletResponse的API设置状态码:

// 设置状态码,状态码在HttpServletResponse中通过一系列的常量预定义了,如SC_ACCEPTED,SC_OK   void setStatus(int sc)


###1.2.3 HTTP响应报文头属性###
**Cache-Control:**响应输出到客户端后,服务端通过该报文头属告诉客户端如何控制响应内容的缓存。下面的设置让客户端对响应内容缓存3600秒,也即在3600秒内,如果客户再次访问该资源,直接从客户端的缓存中返回内容给客户,不要再从服务端获取(当然,这个功能是靠客户端实现的,服务端只是通过这个属性提示客户端“应该这么做”,做不做,还是决定于客户端,如果是自己宣称支持HTTP的客户端,则就应该这样实现)。

Cache-Control: max-age=3600


**ETag:**一个代表响应服务端资源(如页面)版本的报文头属性,如果某个服务端资源发生变化了,这个ETag就会相应发生变化。它是Cache-Control的有益补充,可以让客户端“更智能”地处理什么时候要从服务端取资源,什么时候可以直接从缓存中返回响应。 关于ETag的说明,你可以参见:[http://en.wikipedia.org/wiki/HTTP_ETag](http://en.wikipedia.org/wiki/HTTP_ETag)。 Spring 3.0还专门为此提供了一个`org.springframework.web.filter.ShallowEtagHeaderFilter`(实现原理很简单,对JSP输出的内容MD5,这样内容有变化ETag就相应变化了),用于生成响应的ETag,**因为这东东确实可以帮助减少请求和响应的交互**。下面是一个ETag:

ETag: "737060cd8c284d8af7ad3082f209582d"


**Location:**在JSP中让页面Redirect到一个某个A页面中,其实是让客户端再发一个请求到A页面,这个需要Redirect到的A页面的URL,其实就是通过响应报文头的Location属性告知客户端的,如下的报文头属性,将使客户端redirect到iteye的首页中。

Location: http://www.iteye.com


**Set-Cookie:**服务端可以设置客户端的Cookie,其原理就是通过这个响应报文头属性实现的。

Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1


Connection 使用keep-alive特性; Content-Encoding 使用gzip方式对资源压缩; Content-type MIME类型为html类型,字符集是 UTF-8; Date 响应的日期; Server 使用的WEB服务器; Transfer-Encoding:chunked 分块传输编码 是http中的一种数据传输机制,允许HTTP由网页服务器发送给客户端应用(通常是网页浏览器)的数据可以分成多个部分,分块传输编码只在HTTP协议1.1版本(HTTP/1.1)中提供;


更多其它的HTTP响应头报文,参见:[http://en.wikipedia.org/wiki/List_of_HTTP_header_fields](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields)###1.2.4 如何写HTTP请求报文头###
在服务端可以通过HttpServletResponse的API写响应报文头的属性:

// 添加一个响应报文头属性   void setHeader(String name, String value)


像Cookie,Location这些响应都是有福之人,HttpServletResponse为它们都提供了VIP版的API:

// 添加Cookie报文头属性   void addCookie(Cookie cookie)       // 不但会设置Location的响应报文头,还会生成303的状态码呢,两者天仙配呢   void sendRedirect(String location)


#2 HTTP传输处理#
**在一个网络中。传输数据需要面临三个问题:**> 1. 客户端**如何知道所请求内容的位置**?
> 2. 当客户端知道所请求内容的位置后,**如何获取所请求的内容**?
> 3. 所请求内容以**何种形式组织以便被客户端所识别**?对于WEB来说,回答上面三种问题分别采用三种不同的技术,分别为:**统一资源定位符(URI),超文本传输协议(HTTP)和超文本标记语言(HTML)**。对于大多数WEB开发人员来说URI和HTML都是非常的熟悉。而HTTP协议在很多WEB技术中都被封装的过多使得HTTP反而最不被熟悉。HTTP作为一种传输协议,也是像HTML一样随着时间不断演进的,目前流行的HTTP1.1是HTTP协议的第三个版本。在Internet中所有的传输都是通过TCP/IP进行的。**HTTP协议作为TCP/IP模型中应用层的协议也不例外**。HTTP在网络中的层次如图所示:![HTTP网络层次图](http://upload-images.jianshu.io/upload_images/2062729-646ca06db173fc49.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)可以看出,**HTTP是基于传输层TCP协议的**,而TCP是一个端到端的面向连接的协议。**所谓的端到端可以理解为进程到进程之间的通信**。所以HTTP在开始传输之前,首先需要建立TCP连接,而TCP连接的过程需要所谓的“三次握手”。概念如图所示。![TCP连接三次握手](http://upload-images.jianshu.io/upload_images/2062729-bdc0c6fe5d1d9d2b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)在TCP三次握手之后,建立了TCP连接,此时HTTP就可以进行传输了。一个重要的概念是面向连接,**即HTTP在传输完成之前并不断开TCP连接**。在HTTP1.1中(通过Connection头设置)这是默认行为。所谓的HTTP传输完成,我们通过一个具体的例子来看。比如访问我的博客,使用Fiddler来截取对应的请求和响应。如图所示:![使用Fiddler来截取对应的请求和响应](http://upload-images.jianshu.io/upload_images/2062729-b7d0a109bd2f755d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)可以看出,虽然仅仅访问了我的博客,但所获取的不仅仅是一个HTML,而是浏览器对HTML解析的过程中,如果发现需要获取的内容,会再次发起HTTP请求去服务器获取,比如上图中的那个common2.css。**这上面19个HTTP请求,只依靠一个TCP连接就够了,这就是所谓的持久连接。**也是所谓的一次HTTP请求完成。#3 浏览器解析html代码,并请求html代码中的资源#
浏览器拿到index.html文件后,就开始解析其中的html代码,遇到js/css/image等静态资源时,就向服务器端去请求下载(会使用多线程下载,每个浏览器的线程数不一样),**这个时候就用上keep-alive特性了,建立一次HTTP连接,可以请求多个资源,下载资源的顺序就是按照代码里的顺序**,但是由于每个资源大小不一样,而浏览器又多线程请求请求资源,所以从下图看出,这里显示的顺序并不一定是代码里面的顺序。浏览器在请求静态资源时(在未过期的情况下),向服务器端发起一个http请求(询问自从上一次修改时间到现在有没有对资源进行修改),如果服务器端返回304状态码(告诉浏览器服务器端没有修改),那么浏览器会直接读取本地的该资源的缓存文件。![浏览器请求资源](http://upload-images.jianshu.io/upload_images/2062729-9e0b7a9153cb23bc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)**浏览器具体渲染页面,内部工作原理,请参考:[《前端必读:浏览器内部工作原理》](http://kb.cnblogs.com/page/129756/)**。

转载于:https://my.oschina.net/xianggao/blog/715041

WEB请求处理六:浏览器HTTP协议漫谈相关推荐

  1. WEB HTTP:浏览器HTTP协议漫谈、请求对象Httprequest、响应对象HttpResponse、浏览器内部工作原理(待完善)

    0 系列目录 WEB请求处理 WEB请求处理一:浏览器请求发起处理 WEB请求处理二:Nginx请求反向代理 WEB请求处理三:Servlet容器请求处理 WEB请求处理四:Tomcat配置实践 WE ...

  2. web前端之浏览器篇——http协议知识汇总

    Accept-Charset:浏览器可接受的字符集 User-Agent:告诉HTTP服务器,客户端使用的操作系统和浏览器的名称和版本 Content-Type:例如:Content-Type: ap ...

  3. HTTP协议漫谈 - HTTP协议历史和报文结构

    前言 去年下半年以来各种俗事缠身,所以有段时间没有更新博客了.过完年回来事情不多,项目需求也比较少,又可以愉快的写博客了(≧∇≦)ノ 这几天在网络上搜罗了一些HTTP协议的相关知识,并对这些知识做了一 ...

  4. WEB请求处理二:Nginx请求反向代理

    上一篇<WEB请求处理一:浏览器请求发起处理>,我们讲述了浏览器端请求发起过程,通过DNS域名解析服务器IP,并建立TCP连接,发送HTTP请求.本文将讲述请求到达反向代理服务器的一个处理 ...

  5. WEB 请求处理二:Nginx 请求 反向代理

    上一篇<WEB请求处理一:浏览器请求发起处理>,我们讲述了浏览器端请求发起过程,通过DNS域名解析服务器IP,并建立TCP连接,发送HTTP请求.本文将讲述请求到达反向代理服务器的一个处理 ...

  6. [web面试必备]深入浅出HTTP协议

    1. 基础概念篇 1.1 介绍 HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写.它的发展是万维网协会(World Wide Web Consortium)和 ...

  7. HTTP协议漫谈 C#实现图(Graph) C#实现二叉查找树 浅谈进程同步和互斥的概念 C#实现平衡多路查找树(B树)...

    HTTP协议漫谈 简介 园子里已经有不少介绍HTTP的的好文章.对HTTP的一些细节介绍的比较好,所以本篇文章不会对HTTP的细节进行深究,而是从够高和更结构化的角度将HTTP协议的元素进行分类讲解. ...

  8. Web基础知识之HTTP协议

    HTTP协议 HTTP协议概述 计算机网络体系结构分层 TCP/IP 通信传输流 利用 TCP/IP 协议族进行网络通信时,会通过分层顺序与对方进行通信.发送端从应用层往下走,接收端则从链路层往上走. ...

  9. 【CyberSecurityLearning 52】Web架构安全分析(web工作机制、HTTP协议)

    目录 Web 工作机制 网页.网站 Web容器 静态页面 中间件服务器 数据库的出现 建立一个网站 HTTP 协议概述 概述 特点 URL HTTP 报文分析 HTTP 工作模式 REQUEST 请求 ...

最新文章

  1. 选IDC房时,用脚本截取丢失包和rtt的值作比对
  2. APMServ伪静态设置
  3. 【Linux】Centos7 解压zip文件
  4. SpringCloud相关概念介绍
  5. python 新建html_Python学习第226课——html中创建按钮
  6. 爬虫——————爬取中金所,深交所,上交所期权数据
  7. 使用bash编写Linux shell脚本--复合命令
  8. html正则判断全数字,javascript如何判断是不是数字?
  9. Java知识系统回顾整理01基础04操作符02关系操作符
  10. 圣思园java.doc_北京圣思园java课堂笔记.doc
  11. Halcon PDF文档(hdevelop_users_guide)学习总结之三——关于变量窗口的小知识
  12. oracle设置缓冲区大小设置,描述Oracle优化库高速缓冲区
  13. 服务中没有listen_Odoo 中的 IM(即时通讯)实现分析
  14. Js获取处理日期时间
  15. 深度剖析E680G应用二.MPKG
  16. 牛顿迭代法(求平方根)
  17. PostScript语言教程(六、图形变换)
  18. OpenCv阈值化处理cv2.threshold()函数
  19. 马哥教育N63期-第一周作业
  20. 手写sql语句面试题

热门文章

  1. eclipse打开当前文件所在文件夹
  2. Cisco IOS防火墙的安全规则和配置方案
  3. c语言case可以判断多个条件吗,case 多个条件
  4. K8s卸载清理flannel插件清理
  5. MySQL等值连接的示例
  6. ClassPathScanningCandidateComponentProvider 扫描给定包及其子包的类
  7. Properties作为Map集合的使用
  8. SpringMVC的请求-获得请求参数-获得基本类型参数
  9. aop简介-aop相关概念
  10. flume案例-flume级联-组件分析