HTTP协议

一、HTTP协议

1、简介

超文本传输协议(英文:HyperText Transfer Protocol,缩写:HTTP)是一种用于分布式、协作式和超媒体信息系统的应用层协议。HTTP是万维网的数据通信的基础。

 

HTTP的发展是由蒂姆·伯纳斯-李于1989年在欧洲核子研究组织(CERN)所发起。
HTTP的标准制定由万维网协会(World Wide Web Consortium,W3C)和互联网工程任务组(Internet Engineering Task Force,IETF)进行协调,
最终发布了一系列的RFC,其中最著名的是1999年6月公布的 RFC 2616,定义了HTTP协议中现今广泛使用的一个版本——HTTP 1.1。

 

2014年12月,互联网工程任务组(IETF)的Hypertext Transfer Protocol Bis(httpbis)工作小组将HTTP/2标准提议递交至IESG进行讨论,于2015年2月17日被批准。 HTTP/2标准于2015年5月以RFC 7540正式发表,取代HTTP 1.1成为HTTP的实现标准。

 

2、概述

HTTP是一个客户端终端(用户)和服务器端(网站)请求和应答的标准(TCP)。通过使用网页浏览器、网络爬虫或者其它的工具,客户端发起一个HTTP请求到服务器上指定端口(默认端口为80)。我们称这个客户端为用户代理程序(user agent)。应答的服务器上存储着一些资源,比如HTML文件和图像。我们称这个应答服务器为源服务器(origin server)。在用户代理和源服务器中间可能存在多个“中间层”,比如代理服务器、网关或者隧道(tunnel)。

 

尽管TCP/IP协议是互联网上最流行的应用,HTTP协议中,并没有规定必须使用它或它支持的层。事实上,HTTP可以在任何互联网协议上,或其他网络上实现。HTTP假定其下层协议提供可靠的传输。因此,任何能够提供这种保证的协议都可以被其使用。因此也就是其在TCP/IP协议族使用TCP作为其传输层。

 

通常,由HTTP客户端发起一个请求,创建一个到服务器指定端口(默认是80端口)的TCP连接。HTTP服务器则在那个端口监听客户端的请求。
一旦收到请求,服务器会向客户端返回一个状态,比如"HTTP/1.1 200 OK",以及返回的内容,如请求的文件、错误消息、或者其它信息。

 

3、工作原理

HTTP协议定义Web客户端如何从Web服务器请求Web页面,以及服务器如何把Web页面传送给客户端。HTTP协议采用了请求/响应模型。
客户端向服务器发送一个请求报文,请求报文包含请求的方法、URL、协议版本、请求头部和请求数据。
服务器以一个状态行作为响应,响应的内容包括协议的版本、成功或者错误代码、服务器信息、响应头部和响应数据。

 

HTTP 请求/响应的步骤:
1. 客户端连接到Web服务器
一个HTTP客户端,通常是浏览器,与Web服务器的HTTP端口(默认为80)建立一个TCP套接字连接。例如:https://www.baidu.com/

2. 发送HTTP请求
通过TCP套接字,客户端向Web服务器发送一个文本的请求报文,一个请求报文由请求行、请求头部、空行和请求数据4部分组成。

3. 服务器接受请求并返回HTTP响应
Web服务器解析请求,定位请求资源。服务器将资源复本写到TCP套接字,由客户端读取。一个响应由状态行、响应头部、空行和响应数据4部分组成。

4. 释放连接TCP连接
若connection 模式为close,则服务器主动关闭TCP连接,客户端被动关闭连接,释放TCP连接;若connection 模式为keepalive,则该连接会保持一段时间,在该时间内可以继续接收请求;

5. 客户端浏览器解析HTML内容
客户端浏览器首先解析状态行,查看表明请求是否成功的状态代码。然后解析每一个响应头,响应头告知以下为若干字节的HTML文档和文档的字符集。客户端浏览器读取响应数据HTML,根据HTML的语法对其进行格式化,并在浏览器窗口中显示。

 

例如:

在浏览器地址栏键入URL,按下回车之后会经历以下流程:
浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址;
解析出 IP 地址后,根据该 IP 地址和默认端口 80,和服务器建立TCP连接;
浏览器发出读取文件(URL 中域名后面部分对应的文件)的HTTP 请求,该请求报文作为 TCP 三次握手的第三个报文的数据发送给服务器;
服务器对浏览器请求作出响应,并把对应的 html 文本发送给浏览器;
释放 TCP连接;
浏览器将该 html 文本并显示内容;  

 

4、HTTPS和HTTP的区别

0. http默认端口80,https默认端口是443

1. https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。

2. http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。

3. http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。

4. http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。

扩展资料:
HTTP:是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从WWW服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减少。
HTTPS:是以安全为目标的HTTP通道,简单讲是HTTP的安全版,即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。
HTTPS协议的主要作用可以分为两种:一种是建立一个信息安全通道,来保证数据传输的安全;另一种就是确认网站的真实性。

 

5、请求方法

HTTP/1.1协议中共定义了八种方法(也叫“动作”)来以不同方式操作指定的资源:
GET
向指定的资源发出“显示”请求。使用GET方法应该只用在读取数据,而不应当被用于产生“副作用”的操作中,例如在Web Application中。其中一个原因是GET可能会被网络蜘蛛等随意访问。

 

HEAD
与GET方法一样,都是向服务器发出指定资源的请求。只不过服务器将不传回资源的本文部分。它的好处在于,使用这个方法可以在不必传输全部内容的情况下,就可以获取其中“关于该资源的信息”(元信息或称元数据)。

 

POST
向指定资源提交数据,请求服务器进行处理(例如提交表单或者上传文件)。数据被包含在请求本文中。这个请求可能会创建新的资源或修改现有资源,或二者皆有。

 

PUT
向指定资源位置上传其最新内容。

 

DELETE
请求服务器删除Request-URI所标识的资源。

 

TRACE
回显服务器收到的请求,主要用于测试或诊断。

 

OPTIONS
这个方法可使服务器传回该资源所支持的所有HTTP请求方法。用'*'来代替资源名称,向Web服务器发送OPTIONS请求,可以测试服务器功能是否正常运作。

 

CONNECT
HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。通常用于SSL加密服务器的链接(经由非加密的HTTP代理服务器)。

 

注意事项:
1.方法名称是区分大小写的。当某个请求所针对的资源不支持对应的请求方法的时候,服务器应当返回状态码405(Method Not Allowed),当服务器不认识或者不支持对应的请求方法的时候,应当返回状态码501(Not Implemented)。
2.HTTP服务器至少应该实现GET和HEAD方法,其他方法都是可选的。当然,所有的方法支持的实现都应当匹配下述的方法各自的语义定义。此外,除了上述方法,特定的HTTP服务器还能够扩展自定义的方法。例如PATCH(由 RFC 5789 指定的方法)用于将局部修改应用到资源。

 

6、状态码

所有HTTP响应的第一行都是状态行,依次是当前HTTP版本号,3位数字组成的状态代码,以及描述状态的短语,彼此由空格分隔。

状态代码的第一个数字代表当前响应的类型:
1xx消息被接收等待处理——请求已被服务器接收,等待后续处理
2xx消息成功被接收——请求已成功被服务器接收、理解
3xx重定向——需要后续操作才能完成这一请求
4xx客户端请求错误——请求含有词法错误或者无法被执行
5xx服务器错误——服务器在处理某个正确请求时发生错误
虽然 RFC 2616 中已经推荐了描述状态的短语,例如"200 OK","404 Not Found",但是WEB开发者仍然能够自行决定采用何种短语,用以显示本地化的状态描述或者自定义信息。

1XX 信息性状态码
这些状态码是HTTP 1.1引入的。 对于这些状态码的价值还存在争论 (我个人从来没见过这些状态码, 也没有理解这些状态码。)

100    Continue(继续)                    收到了请求的起始部分,客户端应该继续请求     
101    Switching Protocols(切换协议)    服务器正根据客户端的指示将协议切换成Update Header列出的协议


2开头 (请求成功)表示成功处理了请求的状态代码。
客户端发起请求时, 这些请求通常都是成功的。服务器有一组用来表示成功的状态码,分别对应于不同类型的请求。

200 OK(成功) 服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页(一般是GET请求)。
201 Created(已创建) 请求成功并且服务器创建了新的资源(POST,PUT等create的请求)。 
202 Accepted(已接受) 服务器已接受请求,但尚未处理。 
203 Non-Authoritative Information(非权威信息) 服务器已经成功处理请求,只是实体Header包含的信息不是来自原始服务器,而是来自资源的副本。
204 No Content(无内容) Response中包含一些Header和一个状态行, 但不包括实体的主题内容(没有response body)
205 Reset Content(重置内容) 浏览器应该重置当前页面上所有的HTML表单。
206 Partial Content(部分内容) 部分请求成功。


3开头 (请求被重定向)表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。
重定向状态码用来告诉浏览器客户端,它们访问的资源已被移动, Web服务器发送一个重定向状态码和一个可选的Location Header, 告诉客户端新的资源地址在哪。
浏览器客户端会自动用Location中提供的地址,重新发送新的Request。 这个过程对用户来说是透明的。

300 Multiple Choices(多种选择) 针对请求,服务器可执行多种操作。 客户端请求了实际指向多个资源的URL,这个代码是和一个选项列表一起返回的,然后用户就可以选择他希望的选项了
301 Moved Permanently(永久移动) 请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。
302 Found(临时移动) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
303 See Other(查看其他位置) 请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。(类似302)
304 Not Modified(未修改) 客户的缓存资源是最新的, 要客户端使用缓存。
305  Use Proxy(使用代理) 请求者只能使用代理访问请求的网页。 如果服务器返回此响应,还表示请求者应使用代理。 
307 Temporary Redirect(临时重定向) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。(类似302)


4开头 (请求错误)这些状态代码表示请求可能出错,妨碍了服务器的处理。
有时客户端会发送一些服务器无法处理的东西,比如格式错误的Request, 或者最常见的是, 请求一个不存在的URL。

400 Bad Request(错误请求) 服务器不理解请求的语法。 告诉客户端,它发送了一个错误的请求。
401 Unauthorized(未授权) 请求要求身份验证。 对于需要登录的网页,需要客户端对自己认证。
403 Forbidden(禁止) 服务器拒绝请求。
404 Not Found(未找到) 服务器找不到请求的网页。
405 Method Not Allowed(方法禁用) 禁用请求中指定的方法。 
406 Not Acceptable(不接受) 无法使用请求的内容特性响应请求的网页。 
407 Proxy Authentication Required(需要代理授权) 此状态代码与 401(未授权)类似,但指定请求者应当授权使用代理。
408 Request Timeout(请求超时) 服务器等候请求时发生超时。 
409 Conflict(冲突) 服务器在完成请求时发生冲突。 服务器必须在响应中包含有关冲突的信息。 
410 Gone(已删除) 如果请求的资源已永久删除,服务器就会返回此响应。 
411 Length Required(需要有效长度) 服务器不接受不含有效内容长度标头字段的请求。 
412 Precondition Failed(未满足前提条件) 服务器未满足请求者在请求中设置的其中一个前提条件。 
413 Request Entity Too Large(请求实体过大) 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。 
414 Request URI Too Long(请求的 URI 过长) 请求的 URI(通常为网址)过长,服务器无法处理。 
415 Unsupported Media Type(不支持的媒体类型) 请求的格式不受请求页面的支持。 
416 Requested Range Not Satisfiable(请求范围不符合要求) 如果页面无法提供请求的范围,则服务器会返回此状态代码。 
417 Expectation Failed(未满足期望值) 服务器未满足"期望"请求标头字段的要求。


5开头(服务器错误)这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。
有时候客户端发送了一条有效Request, Web服务器自身却出错了。 可能是Web服务器运行出错了, 或者网站都挂了

500 Internal Server Error(服务器内部错误) 服务器遇到错误,无法完成请求。 
501 Not Implemented(尚未实施) 客户端发起的请求超出服务器的能力范围(比如,使用了服务器不支持的请求方法)时,使用此状态码。
502 Bad Gateway(错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。 
503 Service Unavailable(服务不可用) 服务器目前无法使用(由于超载或停机维护),但过一段时间就可以恢复服务。 
504 Gateway Timeout(网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。 
505 HTTP Version Not Supported(HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。
常见状态码
1xx - 信息提示
这些状态代码表示临时的响应。客户端在收到常规响应之前,应准备接收一个或多个 1xx 响应。

· 100 - Continue 初始的请求已经接受,客户应当继续发送请求的其余部分。(HTTP 1.1新) 
· 101 - Switching Protocols 服务器将遵从客户的请求转换到另外一种协议(HTTP 1.1新)

2xx - 成功
这类状态代码表明服务器成功地接受了客户端请求。

· 200 - OK 一切正常,对GET和POST请求的应答文档跟在后面。 
· 201 - Created 服务器已经创建了文档,Location头给出了它的URL。 
· 202 - Accepted 已经接受请求,但处理尚未完成。 
· 203 - Non-Authoritative Information 文档已经正常地返回,但一些应答头可能不正确,因为使用的是文档的拷贝,非权威性信息(HTTP 1.1新)。
· 204 - No Content 没有新文档,浏览器应该继续显示原来的文档。如果用户定期地刷新页面,而Servlet可以确定用户文档足够新,这个状态代码是很有用的。 
· 205 - Reset Content 没有新的内容,但浏览器应该重置它所显示的内容。用来强制浏览器清除表单输入内容(HTTP 1.1新)。 
· 206 - Partial Content 客户发送了一个带有Range头的GET请求(分块请求),服务器完成了它(HTTP 1.1新)。

3xx - 重定向
客户端浏览器必须采取更多操作来实现请求。例如,浏览器可能不得不请求服务器上的不同的页面,或通过代理服务器重复该请求。

· 300 - Multiple Choices 客户请求的文档可以在多个位置找到,这些位置已经在返回的文档内列出。如果服务器要提出优先选择,则应该在Location应答头指明。 
· 301 - Moved Permanently 客户请求的文档在其他地方,新的URL在Location头中给出,浏览器应该自动地访问新的URL。 
· 302 - Found 类似于301,但新的URL应该被视为临时性的替代,而不是永久性的。注意,在HTTP1.0中对应的状态信息是“Moved Temporatily”。出现该状态代码时,浏览器能够自动访问新的URL,因此它是一个很有用的状态代码。注意这个状态代码有时候可以和301替换使 用。例如,如果浏览器错误地请求 http://host/~user (缺少了后面的斜杠),
有的服务器返回301,有的则返回302。严格地说,我们只能假定只有当原来的请求是GET时浏览器才会自动重定向。请参见307。 
· 303 - See Other 类似于301/302,不同之处在于,如果原来的请求是POST,Location头指定的重定向目标文档应该通过GET提取(HTTP 1.1新)。 
· 304 - Not Modified 客户端有缓冲的文档并发出了一个条件性的请求(一般是提供If-Modified-Since头表示客户只想比指定日期更新的文档)。服务器告诉客户,原来缓冲的文档还可以继续使用。
· 305 - Use Proxy 客户请求的文档应该通过Location头所指明的代理服务器提取(HTTP 1.1新)。 
· 307 - Temporary Redirect 和302(Found)相同。许多浏览器会错误地响应302应答进行重定向,即使原来的请求是POST,即使它实际上只能在POST请求的应答是303时 才能重定向。由于这个原因,HTTP 1.1新增了307,以便更加清除地区分几个状态代码:当出现303应答时,浏览器可以跟随重定向的GET和POST请求;如果是307应答,则浏览器只 能跟随对GET请求的重定向。(HTTP 1.1新)

4xx - 客户端错误
发生错误,客户端似乎有问题。例如,客户端请求不存在的页面,客户端未提供有效的身份验证信息。

· 400 - Bad Request 请求出现语法错误。 
· 401 - Unauthorized 访问被拒绝,客户试图未经授权访问受密码保护的页面。应答中会包含一个WWW-Authenticate头,浏览器据此显示用户名字/密码对话框,然后在 填写合适的Authorization头后再次发出请求。IIS 定义了许多不同的 401 错误,它们指明更为具体的错误原因。这些具体的错误代码在浏览器中显示,但不在 IIS 日志中显示:
· 401.1 - 登录失败。
· 401.2 - 服务器配置导致登录失败。
· 401.3 - 由于 ACL 对资源的限制而未获得授权。
· 401.4 - 筛选器授权失败。
· 401.5 - ISAPI/CGI 应用程序授权失败。
· 401.7 – 访问被 Web 服务器上的 URL 授权策略拒绝。这个错误代码为 IIS 6.0 所专用。
· 403 - Forbidden 资源不可用。服务器理解客户的请求,但拒绝处理它。通常由于服务器上文件或目录的权限设置导致。禁止访问:IIS 定义了许多不同的 403 错误,它们指明更为具体的错误原因:
· 403.1 - 执行访问被禁止。
· 403.2 - 读访问被禁止。
· 403.3 - 写访问被禁止。
· 403.4 - 要求 SSL。
· 403.5 - 要求 SSL 128。
· 403.6 - IP 地址被拒绝。
· 403.7 - 要求客户端证书。
· 403.8 - 站点访问被拒绝。
· 403.9 - 用户数过多。
· 403.10 - 配置无效。
· 403.11 - 密码更改。
· 403.12 - 拒绝访问映射表。
· 403.13 - 客户端证书被吊销。
· 403.14 - 拒绝目录列表。
· 403.15 - 超出客户端访问许可。
· 403.16 - 客户端证书不受信任或无效。
· 403.17 - 客户端证书已过期或尚未生效。
· 403.18 - 在当前的应用程序池中不能执行所请求的 URL。这个错误代码为 IIS 6.0 所专用。
· 403.19 - 不能为这个应用程序池中的客户端执行 CGI。这个错误代码为 IIS 6.0 所专用。
· 403.20 - Passport 登录失败。这个错误代码为 IIS 6.0 所专用。
· 404 - Not Found 无法找到指定位置的资源。这也是一个常用的应答。 
· 404.0 -(无) – 没有找到文件或目录。
· 404.1 - 无法在所请求的端口上访问 Web 站点。
· 404.2 - Web 服务扩展锁定策略阻止本请求。
· 404.3 - MIME 映射策略阻止本请求。
· 405 - Method Not Allowed 请求方法(GET、POST、HEAD、DELETE、PUT、TRACE等)对指定的资源不适用,用来访问本页面的 HTTP 谓词不被允许(方法不被允许)(HTTP 1.1新) 
· 406 - Not Acceptable 指定的资源已经找到,但它的MIME类型和客户在Accpet头中所指定的不兼容,客户端浏览器不接受所请求页面的 MIME 类型(HTTP 1.1新)。 
· 407 - Proxy Authentication Required 要求进行代理身份验证,类似于401,表示客户必须先经过代理服务器的授权。(HTTP 1.1新) 
· 408 - Request Timeout 在服务器许可的等待时间内,客户一直没有发出任何请求。客户可以在以后重复同一请求。(HTTP 1.1新)
· 409 - Conflict 通常和PUT请求有关。由于请求和资源的当前状态相冲突,因此请求不能成功。(HTTP 1.1新) 
· 410 - Gone 所请求的文档已经不再可用,而且服务器不知道应该重定向到哪一个地址。它和404的不同在于,返回407表示文档永久地离开了指定的位置,而404表示由于未知的原因文档不可用。(HTTP 1.1新) 
· 411 - Length Required 服务器不能处理请求,除非客户发送一个Content-Length头。(HTTP 1.1新) 
· 412 - Precondition Failed 请求头中指定的一些前提条件失败(HTTP 1.1新)。
· 413 – Request Entity Too Large 目标文档的大小超过服务器当前愿意处理的大小。如果服务器认为自己能够稍后再处理该请求,则应该提供一个Retry-After头(HTTP 1.1新)。 
· 414 - Request URI Too Long URI太长(HTTP 1.1新)。 
· 415 – 不支持的媒体类型。
· 416 – Requested Range Not Satisfiable 服务器不能满足客户在请求中指定的Range头。(HTTP 1.1新) · 417 – 执行失败。
· 423 – 锁定的错误。

5xx - 服务器错误
服务器由于遇到错误而不能完成该请求。

· 500 - Internal Server Error 服务器遇到了意料不到的情况,不能完成客户的请求。 
· 500.12 - 应用程序正忙于在 Web 服务器上重新启动。
· 500.13 - Web 服务器太忙。
· 500.15 - 不允许直接请求 Global.asa。
· 500.16 – UNC 授权凭据不正确。这个错误代码为 IIS 6.0 所专用。
· 500.18 – URL 授权存储不能打开。这个错误代码为 IIS 6.0 所专用。
· 500.100 - 内部 ASP 错误。
· 501 - Not Implemented 服务器不支持实现请求所需要的功能,页眉值指定了未实现的配置。例如,客户发出了一个服务器不支持的PUT请求。
· 502 - Bad Gateway 服务器作为网关或者代理时,为了完成请求访问下一个服务器,但该服务器返回了非法的应答。 亦说Web 服务器用作网关或代理服务器时收到了无效响应

。
· 502.1 - CGI 应用程序超时。
· 502.2 - CGI 应用程序出错。
· 503 - Service Unavailable 服务不可用,服务器由于维护或者负载过重未能应答。例如,Servlet可能在数据库连接池已满的情况下返回503。服务器返回503时可以提供一个

Retry-After头。这个错误代码为 IIS 6.0 所专用。
· 504 - Gateway Timeout 网关超时,由作为代理或网关的服务器使用,表示不能及时地从远程服务器获得应答。(HTTP 1.1新) 。
· 505 - HTTP Version Not Supported 服务器不支持请求中所指明的HTTP版本。(HTTP 1.1新)
具体状态码

 

7、URL

超文本传输协议(HTTP)的统一资源定位符将从因特网获取信息的五个基本元素包括在一个简单的地址中:

传送协议
层级URL标记符号(为[//],固定不变)
访问资源需要的凭证信息(可省略)
服务器(通常为域名,有时为IP地址)
端口号(以数字方式表示,若为HTTP的默认值“:80”可省略)
路径(以“/”字符区别路径中的每一个目录名称)
查询(GET模式的窗体参数,以“?”字符为起点,每个参数以“&”隔开,再以“=”分开参数名称与数据,通常以UTF8的URL编码,避开字符冲突的问题)
片段   以“#”字符为起点


例如:
https://www.cnblogs.com:443/Zzbj/p/9844520.html

https:协议;
www.cnblogs.com:服务器;
443:服务器上的网络端口号;
/Zzbj/p/9844520.html:路径;


大多数网页浏览器不要求用户输入网页中“http://”的部分,因为绝大多数网页内容是超文本传输协议文件。同样,“80”是超文本传输协议文件的常用端口号,因此一般也不必写明。
一般来说用户只要键入统一资源定位符的一部分(www.cnblogs.com/Zzbj/p/9844520.html)就可以了。

由于超文本传输协议允许服务器将浏览器重定向到另一个网页地址,因此许多服务器允许用户省略网页地址中的部分,比如 www。
从技术上来说这样省略后的网页地址实际上是一个不同的网页地址,浏览器本身无法决定这个新地址是否通,服务器必须完成重定向的任务。

URI与URL

1.URI
URI:统一资源标志符(Uniform Resource Identifier, URI),可以唯一标识一个资源。
是一个用于标识某一互联网资源名称的字符串。 该种标识允许用户对任何(包括本地和互联网)的资源通过特定的协议进行交互操作。
URI由包括确定语法和相关协议的方案所定义。是一个抽象的概念
2.URL URL:统一资源定位符(Uniform Resource Locator),可以提供找到该资源的路径。 URL又是URI,因为它可以标识一个资源,所以URL又是URI的子集。 3.URI和URL之间的区别 URL是URI概念的一种实现方式。 例如:URL是URI 地址:www.baidu.com,这个资源能够唯一标识某个网站资源,它是URL,是URI的一种实现方式 例如:是URI但不是URL 身份证号:6553223413,这个是一人的身份,可以唯一标识这个人,因此它是URI,但它不是URL。

 

8、HTTP请求格式

 

例如:

GET /index/ HTTP/1.1         ---请求行
Host: 127.0.0.1:8080         ---中间的这一大段都是请求头
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
                  ---这空白行是必须要的,代表请求头结束
name=zbj&pwd=123 ---请求数据在这里定义(post请求才能携带请求数据)

 

9、HTTP响应格式

 

 例如

HTTP/1.1 200 OK       ---状态行
Date: Wed, 24 Oct 2018 16:36:24 GMT      ---中间的这一大段是响应头
Content-Type: text/html; charset=UTF-8
                                        ---这空白行是必须的,代表响应头结束
<html>                                  ---响应体
      <head></head>
      <body>
            <h1>嘿嘿嘿!</h1>
      </body>
</html>

 

二、一个HTTP请求的完整流程

"""从浏览器输入www.baidu.com到我们看到页面渲染处理,这整个经过的流程"""

1、整个流程
1.url解析 —> 2.域名解析 —> 3.与服务器建立连接(传输层的TCP协议) —> 4.发起HTTP请求 —> 5. 服务器响应HTTP请求,浏览器得到html代码
  —> 6.浏览器解析html代码,并请求html代码中的资源(如js、css、图片) —> 7.浏览器对页面进行渲染呈现给用户

2、步骤详解
1.为什么url要解析(也就是编码)
因为网络标准规定了URL只能是字母、数字和点,
还有一些其它特殊符号(-_~ ! * ' ( ) ; : @ & = + $ , / ? # [ ],或者中文等等,如果不转义会出现歧义,
比如http://www.baidu.com?key=value,假如我的key本身就包括等于=符号,如ke=y=value,就会出现歧义,
你不知道=到底是连接key和value的符号,还是说本身key里面就有=。
(URL编码只是简单的在特殊字符的各个字节前加上%,即:一个百分号%,后面跟对应字符的ASCII(16进制)码值。例如空格的编码值是"%20")

1.2.url编码的规则
情况1:http://xxxx.com/p/春节   
        注意:"春节"这两个字此时是网址路径的一部分。
        网址路径的编码,用的是utf-8编码
        
情况2:http://xxxx.com/p?day=春节
        注意,"春节"这两个字此时属于查询字符串(参数),不属于网址路径,不要与情况1混淆。
        查询字符串的编码,用的是操作系统的默认编码
        
情况3:在已打开的网页上,直接用Get或Post方法发出HTTP请求
        GET和POST方法的编码,用的是网页的编码
        这时的编码方法由网页的编码决定,也就是由HTML源码中字符集的设定决定。
      <meta http-equiv="Content-Type" content="text/html;charset=xxxx">
        如果上面这一行最后的charset是UTF-8,则URL就以UTF-8编码;如果是GB2312,URL就以GB2312编码
        
        比如在百度和谷歌的搜索框中搜索同一个词"春节"
        百度是GB2312编码,Google是UTF-8编码。因此,从它们的搜索框中搜索同一个词"春节",生成的查询字符串是不一样的。
        百度生成的是%B4%BA%BD%DA,这是GB2312编码。
        
情况4:Ajax调用的URL包含汉字
        在Ajax调用中,IE总是采用GB2312编码(操作系统的默认编码),而Firefox总是采用utf-8编码
        
1.3.有没有办法,能够保证客户端只用一种编码方法向服务器发出请求?
有的,那就是使用Javascript先对URL编码,然后再向服务器提交,不要给浏览器插手的机会。
因为Javascript的输出总是一致的(Javascipt函数的输入和输出,默认都是Unicode字符),所以就保证了服务器得到的数据是格式统一的。

1.4.Javascript编码函数
encodeURI()函数:
    该方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码: - _ . ! ~ * ' ( ) 
    该方法的目的是对 URI 进行完整的编码,因此对以下在 URI 中具有特殊含义的 ASCII 标点符号: ;/?:@&=+$,#
    encodeURI() 函数是不会进行转义的
    它对应的解码函数是decodeURI()。

encodeURIComponent() 函数:
    该方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码: - _ . ! ~ * ' ( ) 
    对于有特殊含义字符(比如 :;/?:@&=+$,# 这些用于分隔 URI 组件的标点符号),都是由一个或多个十六进制的转义序列替换的
    它对应的解码函数是decodeURIComponent()。

encodeURIComponent() 函数 与 encodeURI() 函数的区别之处:
    前者假定它的参数是 URI 的一部分(比如协议、主机名、路径或查询字符串)。
    因此 encodeURIComponent() 函数将转义用于分隔 URI 各个部分的标点符号。

所以:
    如果URL中没有特殊含义字符(;/?:@&=+$,#)的,可以使用encodeURI
    如果URL中有特殊含义字符(;/?:@&=+$,#)的,可以使用encodeURIComponent

"""
URL是一种具体的URI,它是URI的一个子集,它不仅唯一标识资源,而且还提供了定位该资源的信息。
URI 是一种语义上的抽象概念,可以是绝对的,也可以是相对的,而URL则必须提供足够的信息来定位,是绝对的。
"""

2.域名解析
查找浏览器自身(本地)的DNS缓存(缓存时间比较短,大概只有1分钟,且只能容纳1000条缓存),
如果自身的缓存中有www.baidu.com对应的条目,而且没有过期,如果有且没有过期则解析到此结束。

如果在本地缓存上没有找到DNS缓存,那么尝试读取hosts文件(位于C:\Windows\System32\drivers\etc),
看看这里面有没有该域名对应的IP地址,如果有则解析成功。

如果在hosts文件中也没有找到对应的条目,浏览器就会发起一个DNS的系统调用,
DNS解析会从最近的局域网进行查找,如果没有找到,那么继续向上(更大的地方)查找,
直到找到这个域名对应的ip,若没有找到,则解析失败。

2.1.html如何做dns优化
1、DNS预解析
默认情况下浏览器会对页面中和当前域名(正在浏览网页的域名)不在同一个域的域名进行预获取,并且缓存结果,这就是隐式的 DNS Prefetch。
如果想对页面中没有出现的域进行预获取,那么就要使用显示 DNS Prefetch 了。
DNS预解析具体用法
//用meta信息来告知浏览器, 当前页面要做DNS预解析
<meta http-equiv="x-dns-prefetch-control" content="on">
在页面header中使用link标签来强制对DNS预解析: 
<link rel="dns-prefetch" href="//www.xxx.net">

注意:dns-prefetch需慎用,多页面重复DNS预解析会增加重复DNS查询次数,因为有开发者指出 禁用DNS 预读取能节省每月100亿的DNS查询 。
//如果需要禁止隐式的 DNS Prefetch
<meta http-equiv="x-dns-prefetch-control" content="off">



3.与服务器建立连接(传输层)
同步:SYN(synchronize)是请求同步的意思
确认ACK:ACK(acknowledgement)是确认同步的意思,仅当ACK=1时,确认号字段才有效。ACK=0时,确认号无效
确认号ack:因此当前报文段最后一个字节的编号+1即为确认号
序列号:seq(Sequence number)随机产生的顺序号码,用来标记数据段的顺序

3.1三次握手建立TCP连接
第一次握手:
客户端将TCP报文标志位SYN置为1,随机产生一个序号值seq=x,保存在TCP首部的序列号(Sequence Number)字段里,
表示客户端请求同步(请求建立连接),并将该数据包发送给服务器端,发送完毕后,客户端进入SYN_SENT状态,等待服务器端确认。

第二次握手:
服务器端收到客户端发送的数据后,发现客户端的标志位SYN=1,知道客户端请求建立连接,
服务器端把ACK置为1,ack=x+1(客户端的seq+1),表示服务端已经确认,允许建立连接,
然后将自身的标志位SYN也置为1,随机产生一个序号值seq=y,并将该数据包发送给客户端,也向客户端请求同步(请求建立连接),服务器端进入SYN_RCVD状态。

第三次握手:
客户端收到确认后,检查ack是否为x+1,ACK是否为1,如果正确表示服务端同意建立连接,
然后客户端把自身标志位ACK置为1,ack=y+1(服务端的seq+1),发送给服务器端,表示客户端也允许连接建立,
客户端和服务器端进入ESTABLISHED状态,完成三次握手,随后客户端与服务器端之间可以开始传输数据了。


3.2.为什么要三次握手,为啥两次不行
3次握手完成两个重要的功能,既要双方做好发送数据的准备工作(双方都知道彼此已准备好),也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认。
现在把三次握手改成仅需要两次握手,死锁是可能发生的。作为例子,考虑计算机S和C之间的通信,假定C给S发送一个连接请求分组,S收到了这个分组,
并发送了确认应答分组。按照两次握手的协定,S认为连接已经成功地建立了,可以开始发送数据分组。可是,C在S的应答分组在传输中被丢失的情况下,
将不知道S 是否已准备好,不知道S建立什么样的序列号,C甚至怀疑S是否收到自己的连接请求分组。在这种情况下,C认为连接还未建立成功,将忽略S发来的任何数据分组,
只等待连接确认应答分组。而S在发出的分组超时后,重复发送同样的分组。这样就形成了死锁。 4.四次挥手断开TCP连接
加分题,问题是,从网卡把数据包传输出去到服务器发生了什么,参考OSI模型

先从局域网把数据发送到交换机(如果交换机没有缓存本地mac地址和IP地址的映射,此时会通过ARP协议来获得),
交换机的好处是可以隔离冲突域(因为以太网用的是CSMA/CD协议,这个协议规定网线上同一时刻只能有一台机器发送数据),
这样就可以不仅仅同一时刻只有一台机器发送网络包了。
如果目标地址跟发送数据包的源地址在同一个局域网,那么直接通过交换机即可进行数据的发送和接收,如果不在同一个局域网, 交换机会把数据包发送到路由器,路由器相当于公司网关, 路由器具有转发和分组数据包的功能(路由器通过选定的路由协议会构造出路由表,同时不定期的跟相邻路由器交换路由信息), 然后这算是经过了物理层,数据链路层(以太网),开始到网络层进行数据转发了。 然后路由器转发IP数据报,一般的IP地址都会经过NAT转换,让内网的ip也能够访问外网。通过路由器的分组传输,所有数据到达服务器。 然后服务器根据传输层协议进行tcp连接,连接成功后根据tcp包里的端口号,让服务器特定的服务来处理到来的数据包, 并且tcp是面向字节流的(tcp有四大特性,可靠传输、流量控制、拥塞控制、连接管理), 所以我们node的request对象,它的监听事件data事件为什么要用字符串一起拼接起来呢(buffer), 就是因为tcp本身就是字节流,request对象使用的data(http层面)是tcp传来的数据块。 最后数据由传输层转交给应用层,也就是http服务(或者https),后端经过一系列逻辑处理,返回给前端数据。 接着3次握手之后,建立完链接,就该请求html文件了,如果html文件在浏览器缓存里面,浏览器直接返回,如果没有,就去后台拿。 那么缓存是什么? 浏览器首次加载资源成功时,服务器返回200,此时会根据响应报文中HTTP头的缓存标识,决定是否缓存结果,是则将请求结果和缓存标识存入浏览器缓存, 如果需要缓存,意思就是浏览器不仅将资源下载下来,而且把response的header(里面的date属性非常重要,用来计算第二次相同资源时当前时间和date的时间差)一并缓存; 下一次加载资源时,首先要经过强缓存的处理,cache
-control的优先级最高,比如cache-control:no-cache,就直接进入到协商缓存的步骤了, 如果cache-control:max-age=xxx,就会先比较当前时间和上一次返回200时的时间差, 如果没有超过max-age,命中强缓存,不发请求直接从本地缓存读取该文件(这里需要注意,如果没有cache-control,会取expires的值,来对比是否过期), 过期的话会进入下一个阶段,协商缓存。 协商缓存阶段,则向服务器发送header带有If-None-Match和If-Modified-Since的请求,服务器会比较Etag,如果相同,命中协商缓存,返回304; 如果不一致则有改动,直接返回新的资源文件带上新的Etag值并返回200; 协商缓存第二个重要的字段是,If-Modified-Since,如果客户端发送的If-Modified-Since的值跟服务器端获取的文件最近改动的时间,一致则命中协商缓存,返回304; 不一致则返回新的last-modified和文件并返回200; 什么是from disk cache和from memory cache,什么时候会触发? from memory cache 这个资源是直接从内存中拿到的,不会请求服务器,一般已经加载过该资源且缓存在了内存当中, 当关闭该页面时,此资源就被内存释放掉了,再次重新打开相同页面时不会出现from memory cache的情况 from disk cache:此资源是从磁盘当中取出的,也是在已经在之前的某个时间加载过该资源, 不会请求服务器,但是此资源不会随着该页面的关闭而释放掉,因为是存在硬盘当中的,下次打开仍会from disk cache 接着返回html之后,会解析html,大概就是cssom + domTree = html,然后布局和绘制 构建DOM树(DOM tree):从上到下解析HTML文档生成DOM节点树(DOM tree),也叫内容树(content tree); 构建CSSOM(CSS Object Model)树:加载解析样式生成CSSOM树; 执行JavaScript:加载并执行JavaScript代码(包括内联代码或外联JavaScript文件); 构建渲染树(render tree):根据DOM树和CSSOM树,生成渲染树(render tree); 渲染树:按顺序展示在屏幕上的一系列矩形,这些矩形带有字体,颜色和尺寸等视觉属性。 布局(layout):根据渲染树将节点树的每一个节点布局在屏幕上的正确位置; 绘制(painting):遍历渲染树绘制所有节点,为每一个节点适用对应的样式,这一过程是通过UI后端模块完成; 接着面试官问我一些页面渲染层的一些优化手段,大概如下: 页面渲染优化 HTML文档结构层次尽量少,最好不深于六层; 脚本尽量后放,放在前即可; 少量首屏样式内联放在标签内; 样式结构层次尽量简单; 在脚本中尽量减少DOM操作,尽量缓存访问DOM的样式信息,避免过度触发回流; 减少通过JavaScript代码修改元素样式,尽量使用修改class名方式操作样式或动画; 动画尽量使用在绝对定位或固定定位的元素上; 隐藏在屏幕外,或在页面滚动时,尽量停止动画; 尽量缓存DOM查找,查找器尽量简洁; 涉及多域名的网站,可以开启域名预解析 最后面试官问我,如何诊断页面渲染时各个性能指标, 我大概说了,通过chrome浏览器的工具,比如看网络请求情况的network,还有看页面渲染情况的perfermance

 

三、http缓存

原文:https://blog.csdn.net/michael1112/article/details/78830382

1、http 缓存分为客户端缓存和服务端缓存

1. 客户端缓存

客户端缓存指的是浏览器缓存, 浏览器缓存是最快的缓存, 因为它直接从本地获取(但有可能需要发送一个请求), 它的优势是可以减少网络流量, 加快请求速度

 

2. 服务器缓存

服务器缓存指的是反向代理服务器或 cdn 缓存, 他的作用是用于减轻实际的 web server 的压力.

 

2、缓存生效都是通过 header 来控制的

1. Expires

如果 repsonse 中带有 Expires=date, 则表示这个 response 可以由 浏览器/CDN 保存至 date 日期, 在到达 date 日期之前, 都可以直接提供给请求方, 对于浏览器缓存来说, 则可以不必发请求, 对于反向代理服务器来说, 则可以不用请求原始 server

2. Cache-Control

Cache-Control 的值有很多, 最常用的是 max-age, 如果 response 带有 max-age, 则表示从现在起到 max-age 之前, 这个 repsonse 都可以作为缓存使用

Server 的 Cache-Control
1. no-store, 提示客户端应该删除这个缓存
2. no-cache, 提示客户端在重新验证这个缓存之前不应该使用
3. max-age, 表示缓存的新鲜时间, 在此时间内可以不发送 http 请求去验证缓存而直接使用它, 如果 max-age=0. 则表示要求不要缓存文档
4. s-maxage, 功能与 max-age 相同, 但只对共享缓存生效(CDN, 反向代理)

Client 的 Cache-Control
1. max-stale, 可以使用过期缓存
2. max-stale=s, 在 s 秒内, 缓存可以过期
3. min-fresh=s, 在 s 秒内, 缓存不能过期
4. max=age=s, 缓存的 age 必须小于 s 秒 
5. no-cache, 除非资源进行再验证, 否则不接受缓存
6. no-store, 表示反向代理服务器不应该缓存这个请求的 response
7. only-if-cached, 只想要已缓存的数据, 否则返回 504

如果 Cache-Control 的 max-age 与 Expires 同时存在, 则 max-age 优先

3. Last-Modified/If-Modified-Since

如果 response 带有 Last-Modified, 则 request 在 Expires 跟 Cache-Control 的缓存过期后, 可以使用将 Last-Modified 的时间带到 request header If-Modified-Since 里, 去 server 端校验缓存是否改变, 如果  server 回复 304, 则可以继续使用本地缓存

4. ETag/If-None-Match

如果 response  带有 ETag, 则 request 在 Expires 跟 Cache-Control 的缓存过期后, 可以将 Etag 的值带到 request header If-None-Match, 如果  server 回复 304, 则可以继续使用本地缓存

5. ETag & Last-Modified

如果 response 同时包含 ETag 与 Last-Modified, 则 request 需要同时发送 If-Modified-Since 和 If-None-Match, 并且 server 需要两者同时校验通过才返回 304.

 

posted @ 2018-10-24 17:02  我用python写Bug  阅读(458)  评论(0编辑  收藏  举报