【网络学习】HTTP(HyperText Transfer Protocol,超文本传输协议),HTTPS

1,概念

HTTP协议(HyperText Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准。

HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。

1)请求方法

根据HTTP标准,HTTP请求可以使用多种请求方法。
HTTP1.0定义了三种请求方法: GET、POST 和 HEAD方法。
HTTP1.1新增了五种请求方法:OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT 方法。

2)简单请求与预检请求

①简单请求

HTTP 1.0 三个方法:HEAD、GET、POST 默认都属于简单请求 Simple Request。
特点:

  • 没有自定义报头
  • MIME Type in text/plain、multipart/form-data、application/x-www-form-urlencoded

3)消息结构

HTTP是基于客户端/服务端(C/S)的架构模型,通过一个可靠的链接来交换信息,是一个无状态的请求/响应协议。

1>客户端:浏览器

2>服务端:Web服务器

包括Apache服务器,IIS服务器(Internet Information Services)等。

Web服务器根据接收到的请求后,向客户端发送响应信息。
HTTP默认端口号为80,但是你也可以改为8080或者其他端口。

3>传输:统一资源标识符(Uniform Resource Identifiers, URI)

HTTP使用URI来传输数据和建立连接。
一旦建立连接后,数据消息就通过类似Internet邮件所使用的格式[RFC5322]和多用途Internet邮件扩展(MIME)[RFC2045]来传送。

4>注意事项:

  • HTTP是无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
  • HTTP是媒体独立的:这意味着,只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过HTTP发送。客户端以及服务器指定使用适合的MIME-type内容类型。
  • HTTP是无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

5>URL

URL是一种特殊类型的URI,包含了用于查找某个资源的足够的信息URL,全称是UniformResourceLocator, 中文叫统一资源定位符,是互联网上用来标识某一处资源的地址。
举例:http://www.aspxfans.com:8080/news/index.asp?boardID=5&ID=24618&page=1#name
从上面的URL可以看出,一个完整的URL包括以下几部分:

  1. 协议部分:该URL的协议部分为“http:”,这代表网页使用的是HTTP协议。在Internet中可以使用多种协议,如HTTP,FTP等等本例中使用的是HTTP协议。在"HTTP"后面的“//”为分隔符
  2. 域名部分:该URL的域名部分为“www.aspxfans.com”。一个URL中,也可以使用IP地址作为域名使用
  3. 端口部分:跟在域名后面的是端口,域名和端口之间使用“:”作为分隔符。端口不是一个URL必须的部分,如果省略端口部分,将采用默认端口
  4. 虚拟目录部分:从域名后的第一个“/”开始到最后一个“/”为止,是虚拟目录部分。虚拟目录也不是一个URL必须的部分。本例中的虚拟目录是“/news/”
  5. 文件名部分:从域名后的最后一个“/”开始到“?”为止,是文件名部分,如果没有“?”,则是从域名后的最后一个“/”开始到“#”为止,是文件部分,如果没有“?”和“#”,那么从域名后的最后一个“/”开始到结束,都是文件名部分。本例中的文件名是“index.asp”。文件名部分也不是一个URL必须的部分,如果省略该部分,则使用默认的文件名
  6. 锚部分:从“#”开始到最后,都是锚部分。本例中的锚部分是“name”。锚部分也不是一个URL必须的部分
  7. 参数部分:从“?”开始到“#”为止之间的部分为参数部分,又称搜索部分、查询部分。本例中的参数部分为“boardID=5&ID=24618&page=1”。参数可以允许有多个参数,参数与参数之间用“&”作为分隔符。

4)Rest:

一种基于HTTP协议的API约束规则。REST接口是面向资源的,通过资源(Resources)来暴露数据(data)和算法(algorithms)。

2,HTTP method对照

1)DELETE(删除)

场景

用于删除资源

方法与规范

其实虽然我们都说 POST(增) DELETE(删)PUT(改)GET(查),但其实真正我们是如何实现方法的是随意的,也就是你完全可以用 GET 删除资源,DELETE 增加资源,但这样是不规范的。

2)GET(获取)

场景

获取资源。

参数特点

a) 参数明文

敏感信息不建议使用 GET 方法。

b) 数据类型只允许 ASCII

传递 二进制 文件就能用 GET 方法。
如果数据是英文字母/数字,原样发送,如果是空格,转换为+,如果是中文/其他字符,则直接把字符串用BASE64加密,得出如: %E4%BD%A0%E5%A5%BD,其中%XX中的XX为该符号以16进制表示的ASCII。

c)可以保存书签

当我们访问某一个网站的频率特别高的时候,肯定添加到书签,那其实书签就是依靠 GET 方法来保存的。

d) 可以被缓存

GET 方法支持缓存,当本次请求允许被缓存时,会将资源存值本地 cache ,在未过期的情况下直接取本地 cache;缓存过期后视情况而定。

e) 参数会保留在浏览器历史记录

比较直观的感受就是,我们可以在浏览器的历史记录中查看到曾经搜索过的关键字信息。

f) 请求长度会受限

不同的浏览器对于 GET 请求长度的限制也是不同的,注意这是 浏览器 / 服务器(IE、Chrome、Apache、IIS等) 对于长度的限制,而不是 HTTP 协议。
通常GET方式提交的数据不能大于2KB(主要是URL长度限制)。
IE对URL长度的限制是2083字节(2K+35)。对于其他浏览器,如Netscape、FireFox等,理论上没有长度限制,其限制取决于操作系 统的支持。

4)OPTIONS

场景

OPTIONS 方法的首要目的是 Priflight Request(预检请求)。

为什么要发预检请求?

我们都知道浏览器的同源策略,就是出于安全考虑,浏览器会限制从脚本发起的跨域HTTP请求,像XMLHttpRequest和Fetch都遵循同源策略。
浏览器限制跨域请求一般有两种方式:

浏览器限制发起跨域请求
跨域请求可以正常发起,但是返回的结果被浏览器拦截了

一般浏览器都是第二种方式限制跨域请求,那就是说请求已到达服务器,并有可能对数据库里的数据进行了操作,但是返回的结果被浏览器拦截了,那么我们就获取不到返回结果,这是一次失败的请求,但是可能对数据库里的数据产生了影响。

为了防止这种情况的发生,规范要求,对这种可能对服务器数据产生副作用的HTTP请求方法,浏览器必须先使用OPTIONS方法发起一个预检请求,从而获知服务器是否允许该跨域请求:如果允许,就发送带数据的真实请求;如果不允许,则阻止发送带数据的真实请求。

预检请求的范围:
一般 HTTP1.1 中的方法请求默认都会触发预检请求,但是简单请求满足一下条件也可以触发 Options 请求。
特点:

  • 带有自定义头信息
  • MIME Type Not in text/plain、multipart/form-data、application/x-www-form-urlencoded

方法特点

假如我现在有如下配置:

Access-Control-Allow-Methods:OPTIONS, PUT

那么当浏览器发起了 Priflight Request 后,只在包含在 被允许的 HTTP 方法中的请求会被通过(Simple Request除外),而没有被包含在内的请求,例如 DELETE 在OPTIONS 之后将不会被请求。

5)POST(新增)

场景

POST 方法的首要目的是 提交,POST 方法一般用于添加资源。
有时候也用于大量检索参数的获取资源。

方法特点

a) 参数不可见,也不会被保存

所以说 POST 方法是不可以被保存书签,也不可以被缓存,也不可以被保存在浏览器历史中,

b) 不限制请求长度

对于 POST 方法这种以 提交 为首要目的的方法,肯定是不可以限制请求长度的。
对于有些特殊GET方法,由于URI长度超限,所以改为POST方法进行资源的获取。

c) 数据类型

不限,所以说 POST 是可以 提交文件 到服务器的。

d) 请求方式

POST 请求与 GET 请求不同,他会首先提交 HEAD 信息,待得到 100 响应后,才会再次将 DATA 提交。

6)PUT(修改)

场景

PUT 与 PATCH 方法都是用于更新资源。

方法特点

PUT 对后台来说 PUT 方法的参数是一个完整的资源对象,它包含了对象的所有字段。

7)PATCH

场景

PUT 与 PATCH 方法都是用于更新资源;PATCH是对 PUT 方法的补充,用来对已知资源进行局部更新 。

方法特点

PATCH 对后台来说 PATCH 方法的参数只包含我们需要修改的资源对象的字段。

8)HEAD

场景

获取报头信息,例如检查 cache 是否被修改,是否过期?

方法特点

HEAD 方法与 GET 方法类似,但并不会返回响应主体。

9)TRACE

场景

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

10)CONNECT

场景

HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。

3,请求消息Request

【网络学习】HTTP(HyperText Transfer Protocol,超文本传输协议),HTTPS_第1张图片Get请求例子,使用Charles抓取的request:

GET /562f25980001b1b106000338.jpg HTTP/1.1
Host    img.mukewang.com
User-Agent    Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36
Accept    image/webp,image/*,*/*;q=0.8
Referer    http://www.imooc.com/
Accept-Encoding    gzip, deflate, sdch
Accept-Language    zh-CN,zh;q=0.8

客户端发送一个HTTP请求到服务器的请求消息包括以下格式:

1)请求行(request line)

以一个方法符号开头,以空格分开,后面跟着请求的URI和协议的版本。
用来说明请求类型,要访问的资源以及所使用的HTTP版本。

GET说明请求类型为GET,[/562f25980001b1b106000338.jpg]为要访问的资源,该行的最后一部分说明使用的是HTTP1.1版本。

2)请求头部(header)

紧接着请求行(即第一行)之后的部分,用来说明服务器要使用的附加信息。

从第二行起为请求头部:
HOST将指出请求的目的地;
User-Agent 服务器端和客户端脚本都能访问它,它是浏览器类型检测逻辑的重要基础。该信息由你的浏览器来定义,并且在每个请求中自动发送等等。

3)空行

请求头部后面的空行是必须的;即使第四部分的请求数据为空,也必须有空行。

4)请求数据(请求主体)

可以添加任意的其他数据。

4,响应消息Response

一般情况下,服务器接收并处理客户端发过来的请求后会返回一个HTTP的响应消息。

HTTP/1.1 200 OK
Date: Fri, 22 May 2009 06:07:21 GMT
Content-Type: text/html; charset=UTF-8

<html>
      <head>head>
      <body>
            
      body>
html>

HTTP响应也由四个部分组成:

1)状态行

第一行为状态行,由HTTP协议版本号(HTTP/1.1), 状态码(200), 状态消息(ok)三部分组成。

2)消息报头

用来说明客户端要使用的一些附加信息。
Date:生成响应的日期和时间;Content-Type:指定了MIME类型的HTML(text/html),编码类型是UTF-8。

3)空行

消息报头后面的空行是必须的。

4)响应正文

服务器返回给客户端的文本信息。
空行后面的html部分为响应正文。

5,HTTP 响应头信息

HTTP请求头提供了关于请求,响应或者其他的发送实体的信息。

1)Allow

服务器支持哪些请求方法(如GET、POST等)。

2)Content-Encoding

文档的编码(Encode)方法。

3)Content-Length

表示内容长度。
只有当浏览器使用持久HTTP连接时才需要这个数据。如果你想要利用持久连接的优势,可以把输出文档写入 ByteArrayOutputStream,完成后查看其大小,然后把该值放入Content-Length头,最后通过byteArrayStream.writeTo(response.getOutputStream()发送内容。

4)Content-Type

表示后面的文档属于什么MIME类型。
Servlet默认为text/plain,但通常需要显式地指定为text/html。由于经常要设置Content-Type,因此HttpServletResponse提供了一个专用的方法setContentType。

5)Date

当前的GMT时间。
可以用setDateHeader来设置这个头以避免转换时间格式的麻烦。

6)Expires

应该在什么时候认为文档已经过期,从而不再缓存它?

7)Last-Modified

文档的最后改动时间。
客户可以通过If-Modified-Since请求头提供一个日期,该请求将被视为一个条件GET,只有改动时间迟于指定时间的文档才会返回,否则返回一个304(Not Modified)状态。Last-Modified也可用setDateHeader方法来设置。

8)Location

表示客户应当到哪里去提取文档。
Location通常不是直接设置的,而是通过HttpServletResponse的sendRedirect方法,该方法同时设置状态代码为302。

9)Refresh

表示浏览器应该在多少时间之后刷新文档,以秒计。
除了刷新当前文档之外,你还可以通过setHeader(“Refresh”, “5; URL=http://host/path”)让浏览器读取指定的页面。

10)Server

服务器名字。
Servlet一般不设置这个值,而是由Web服务器自己设置。

11)Set-Cookie

设置和页面关联的Cookie。
Servlet不应使用response.setHeader(“Set-Cookie”, …),而是应使用HttpServletResponse提供的专用方法addCookie。

12)WWW-Authenticate

客户应该在Authorization头中提供什么类型的授权信息?
在包含401(Unauthorized)状态行的应答中这个头是必需的。例如,response.setHeader(“WWW-Authenticate”, “BASIC realm=\“executives\””)。
注意Servlet一般不进行这方面的处理,而是让Web服务器的专门机制来控制受密码保护页面的访问(例如.htaccess)。

6,HTTP状态码

常见状态码:

200 - 请求成功
301 - 资源(网页等)被永久转移到其它URL
404 - 请求的资源(网页等)不存在
500 - 内部服务器错误

1)HTTP状态码分类

分类 分类描述
1** 指示信息,表示请求已接收,继续处理
2** 成功,操作被成功接收并处理
3** 重定向,需要进一步的操作以完成请求
4** 客户端错误,请求包含语法错误或无法完成请求
5** 服务器错误,服务器在处理请求的过程中发生了错误

2)状态码大全

状态码 状态码英文名称 中文描述
100 Continue 继续。客户端应继续其请求
101 Switching Protocols 切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议
200 OK 请求成功。一般用于GET与POST请求
201 Created 已创建。成功请求并创建了新的资源
202 Accepted 已接受。已经接受请求,但未处理完成
203 Non-Authoritative Information 非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本
204 No Content 无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档
205 Reset Content 重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域
206 Partial Content 部分内容。服务器成功处理了部分GET请求
300 Multiple Choices 多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择
301 Moved Permanently 永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替
302 Found 临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI
303 See Other 查看其它地址。与301类似。使用GET和POST请求查看
304 Not Modified 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源
305 Use Proxy 使用代理。所请求的资源必须通过代理访问
306 Unused 已经被废弃的HTTP状态码
307 Temporary Redirect 临时重定向。与302类似。使用GET请求重定向
400 Bad Request 客户端请求的语法错误,服务器无法理解
401 Unauthorized 请求要求用户的身份认证
402 Payment Required 保留,将来使用
403 Forbidden 服务器理解请求客户端的请求,但是拒绝执行此请求
404 Not Found 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面
405 Method Not Allowed 客户端请求中的方法被禁止
406 Not Acceptable 服务器无法根据客户端请求的内容特性完成请求
407 Proxy Authentication Required 请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权
408 Request Time-out 服务器等待客户端发送的请求时间过长,超时
409 Conflict 服务器完成客户端的 PUT 请求时可能返回此代码,服务器处理请求时发生了冲突
410 Gone 客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置
411 Length Required 服务器无法处理客户端发送的不带Content-Length的请求信息
412 Precondition Failed 客户端请求信息的先决条件错误
413 Request Entity Too Large 由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息
414 Request-URI Too Large 请求的URI过长(URI通常为网址),服务器无法处理
415 Unsupported Media Type 服务器无法处理请求附带的媒体格式
416 Requested range not satisfiable 客户端请求的范围无效
417 Expectation Failed 服务器无法满足Expect的请求头信息
500 Internal Server Error 服务器内部错误,无法完成请求
501 Not Implemented 服务器不支持请求的功能,无法完成请求
502 Bad Gateway 作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应
503 Service Unavailable 由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中
504 Gateway Time-out 充当网关或代理的服务器,未及时从远端服务器获取请求
505 HTTP Version not supported 服务器不支持请求的HTTP协议的版本,无法完成处理

7,REST API规范

目前没有统一的标准规范,以下列举的是一些常用规范。

1)服务地址

{schema}/{host}:{port}/{prefix}/{version}/{resource}
其中schema表示API接口支持的协议(http或https),如:http://10.0.0.1:8080/api/v1/dashborads

控制类接口:使用动词去显式地表达API的语义,统一格式为:/{prefix}/{version}/{resources}/{action}

2)api名称(资源名称)

  1. 小写,用“-”连接;
  2. 尽量不出现动词;
  3. 父级用资源的复数形式表示;
  4. 用查询变量(条件参数)表达算法的输入,如:/search?page=1&num=20
  5. 资源名称为变量参数时,用{resourceId}表示,如:/dashboards/{dashboardId,}
  6. 资源名称为复数时,其响应必为列表;资源名称为单数时,其响应必为字典(单条数据)。

3)向下兼容

  1. 由于一个API服务可以提供多个API接口,如果有不兼容和破坏性的更改,版本号将让你能更容易的发布API;如GET /api/1.0/…… GET /api/2.0/……

4)参数

  1. GET, DELETE, HEAD 方法,参数风格必须为标准的 GET 风格的参数,如 ?a=1&b=2;POST, PUT, PATCH, OPTIONS 方法 默认情况下请求实体会被视作标准 json 字符串进行处理,应该设置头信息的 Content-Type 为 application/json,在一些特殊接口中,可以允许 Content-Type 为 application/x-www-form-urlencoded 或者 multipart/form-data ,此时请求实体会被视作标准 POST 风格的参数进行处理;在特殊场景下,例如查询参数长度超过浏览器限制、不允许使用DELETE方法等,可以使用POST方法代替。
  2. 参数名为动词-名次,不应该包含介词。
  3. 参数命名: 驼峰,首字母小写。groupName

5)method

POST 创建一个新的资源
GET 获取指定资源
PUT 更新指定资源
DELETE 删除指定资源
OPTIONS 获取指定资源支持的HTTP方法

6)响应约束

如调用方在请求头Accept中无具体指定,所有API响应数据类型默认为:application/json;否则以请求头中Accept指定的数据格式响应。

8,HTTP与HTTPS

1)区别

http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。http的连接很简单,是无状态的。HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全。
HTTPS是一种通过计算机网络进行安全通信的传输协议。HTTPS经由HTTP进行通信,但利用SSL/TLS来加密数据包。HTTPS开发的主要目的,是提供对网站服务器的身份认证,保护交换数据的隐私与完整性。

SSL(安全套接层,secure sockets layer)
TLS(传输层安全,transport layer security),是SSL的继任者。
安全层其实就是在明文的上层和TCP层之间加上一层加密,这样就保证上层信息传输的安全。

【网络学习】HTTP(HyperText Transfer Protocol,超文本传输协议),HTTPS_第2张图片
注:TLS是SSL的升级替代版,具体发展历史可以参考传输层安全性协议。

HTTP与HTTPS在写法上的区别也是前缀的不同,客户端处理的方式也不同,具体说来:
如果URL的协议是HTTP,则客户端会打开一条到服务端端口80(默认)的连接,并向其发送老的HTTP请求。
如果URL的协议是HTTPS,则客户端会打开一条到服务端端口443(默认)的连接,然后与服务器握手,以二进制格式与服务器交换一些SSL的安全参数,附上加密的 HTTP请求。

所以HTTPS比HTTP多了一层与SSL的连接,这也就是客户端与服务端SSL握手的过程,整个过程主要完成以下工作:

  • 交换协议版本号
  • 选择一个两端都了解的密码
  • 对两端的身份进行认证
  • 生成临时的会话密钥,以便加密信道。
    SSL握手是一个相对比较复杂的过程,更多关于SSL握手的过程细节可以参考TLS/SSL握手过程

SSL/TSL的常见开源实现是OpenSSL,OpenSSL是一个开放源代码的软件库包,应用程序可以使用这个包来进行安全通信,避免窃听,同时确认另一端连接者的身份。这个包广泛被应用在互联网的网页服务器上。 更多源于OpenSSL的技术细节可以参考OpenSSL。

2)HTTP缓存

HTTP的缓存机制也是依赖于请求和响应header里的参数类实现的,最终响应式从缓存中去,还是从服务端重新拉取,HTTP的缓存机制的流程如下所示:
【网络学习】HTTP(HyperText Transfer Protocol,超文本传输协议),HTTPS_第3张图片
HTTP的缓存可以分为两种:
①强制缓存
需要服务端参与判断是否继续使用缓存,当客户端第一次请求数据是,服务端返回了缓存的过期时间(Expires与Cache-Control),没有过期就可以继续使用缓存,否则则不适用,无需再向服务端询问。
②对比缓存
需要服务端参与判断是否继续使用缓存,当客户端第一次请求数据时,服务端会将缓存标识(Last-Modified/If-Modified-Since与Etag/If-None-Match)与数据一起返回给客户端,客户端将两者都备份到缓存中 ,再次请求数据时,客户端将上次备份的缓存 标识发送给服务端,服务端根据缓存标识进行判断,如果返回304,则表示通知客户端可以继续使用缓存。
强制缓存优先于对比缓存。
上面提到强制缓存使用的的两个标识:

  • Expires
    Expires的值为服务端返回的到期时间,即下一次请求时,请求时间小于服务端返回的到期时间,直接使用缓存数据。到期时间是服务端生成的,客户端和服务端的时间可能有误差。
  • Cache-Control
    Expires有个时间校验的问题,所有HTTP1.1采用Cache-Control替代Expires。
    Cache-Control的取值有以下几种:

private: 客户端可以缓存。
public: 客户端和代理服务器都可缓存。
max-age=xxx: 缓存的内容将在 xxx 秒后失效
no-cache: 需要使用对比缓存来验证缓存数据。
no-store: 所有内容都不会缓存,强制缓存,对比缓存都不会触发。
我们再来看看对比缓存的两个标识:

  • Last-Modified/If-Modified-Since
    Last-Modified 表示资源上次修改的时间。
    当客户端发送第一次请求时,服务端返回资源上次修改的时间:
    Last-Modified: Tue, 12 Jan 2016 09:31:27 GMT
    客户端再次发送,会在header里携带If-Modified-Since。将上次服务端返回的资源时间上传给服务端。

If-Modified-Since: Tue, 12 Jan 2016 09:31:27 GMT
服务端接收到客户端发来的资源修改时间,与自己当前的资源修改时间进行对比,如果自己的资源修改时间大于客户端发来的资源修改时间,则说明资源做过修改, 则返回200表示需要重新请求资源,否则返回304表示资源没有被修改,可以继续使用缓存。

上面是一种时间戳标记资源是否修改的方法,还有一种资源标识码ETag的方式来标记是否修改,如果标识码发生改变,则说明资源已经被修改,ETag优先级高于Last-Modified。

  • Etag/If-None-Match
    ETag是资源文件的一种标识码,当客户端发送第一次请求时,服务端会返回当前资源的标识码:
    ETag: “5694c7ef-24dc”
    客户端再次发送,会在header里携带上次服务端返回的资源标识码:

If-None-Match:“5694c7ef-24dc”
服务端接收到客户端发来的资源标识码,则会与自己当前的资源吗进行比较,如果不同,则说明资源已经被修改,则返回200,如果相同则说明资源没有被修改,返回 304,客户端可以继续使用缓存。

3)HTTPS是如何保证安全的,证书如何校验?

4)HTTP如何实现长连接?

9,HTTP工作原理

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

以下是 HTTP 请求/响应的步骤:

  1. 客户端连接到Web服务器
    一个HTTP客户端,通常是浏览器,与Web服务器的HTTP端口(默认为80)建立一个TCP套接字连接。例如,http://www.oakcms.cn。
  2. 发送HTTP请求
    通过TCP套接字,客户端向Web服务器发送一个文本的请求报文,一个请求报文由请求行、请求头部、空行和请求数据4部分组成。
  3. 服务器接受请求并返回HTTP响应
    Web服务器解析请求,定位请求资源。服务器将资源复本写到TCP套接字,由客户端读取。一个响应由状态行、响应头部、空行和响应数据4部分组成。
  4. 释放连接TCP连接
    若connection 模式为close,则服务器主动关闭TCP连接,客户端被动关闭连接,释放TCP连接;若connection 模式为keepalive,则该连接会保持一段时间,在该时间内可以继续接收请求;
  5. 客户端浏览器解析HTML内容
    客户端浏览器首先解析状态行,查看表明请求是否成功的状态代码。然后解析每一个响应头,响应头告知以下为若干字节的HTML文档和文档的字符集。客户端浏览器读取响应数据HTML,根据HTML的语法对其进行格式化,并在浏览器窗口中显示。
    例如:在浏览器地址栏键入URL,按下回车之后会经历以下流程:
    a. 浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址;
    b. 解析出 IP 地址后,根据该 IP 地址和默认端口 80,和服务器建立TCP连接;
    c. 浏览器发出读取文件(URL 中域名后面部分对应的文件)的HTTP 请求,该请求报文作为 TCP 三次握手的第三个报文的数据发送给服务器;
    d. 服务器对浏览器请求作出响应,并把对应的 html 文本发送给浏览器;
    e. 释放 TCP连接;
    f. 浏览器将该 html 文本并显示内容;

10,Android中的http使用

Android中主要提供了两种方式来进行HTTP操作,HttpURLConnection和HttpClient。这两种方式都支持HTTPS协议、以流的形式进行上传和下载、配置超时时间、IPv6、以及连接池等功能。

1)HttpURLConnection

获取HttpURLConnection的实例:

URL url = new URL("http://www.baidu.com");
HttpURLConnection connection = (HttpURLConnection)url.openConnection();

设置一下HTTP请求所使用的方法,常用的方法主要有两个GET和POST,GET表示希望从服务器那里获取数据,而POST则表示希望提交数据给服务器:

connection.setRequestMethod("GET");

网络定制:比如设置链接超时,读取超时的毫秒数,以及服务器希望得到的一些消息头等。

connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);

调用getInputStream()方法获取到服务器返回的输入流:

InputStream in = connection.getInputStream();

调用disconnect()方法可以将HTTP链接关闭:

connection.disconnect();

流的读取:

reader = new BufferedReader(new InputStreamReader(in));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null){
     response.append(line);
}
showResponse(response.toString());
//reader.close();记得最后关闭

2)HttpClient方式(过时)

包含HttpGet和HttpPost类。Android6.0开始过时,官方推荐HttpURLConnection。

①概念

HttpClient是Apache开源组织提供的HTTP网络访问接口(一个开源的项目),是一个简单的HTTP客户端(并不是浏览器),可以发送HTTP请求,接受HTTP响应。但是不会缓存服务器的响应,不能执行HTTP页面中签入嵌入的JS代码,自然也不会对页面内容进行任何解析、处理,这些都是需要开发人员来完成的。
现在Android已经成功集成了HttpClient,所以开发人员在Android项目中可以直接使用HttpClient来想Web站点提交请求以及接受响应,如果使用其他的Java项目,需要引入进相应的Jar包。

HttpClient其实是一个interface类型,HttpClient封装了对象需要执行的Http请求、身份验证、连接管理和其它特性。既然HttpClient是一个接口,因此无法创建它的实例。从文档上看,HttpClient有三个已知的实现类分别是:AbstractHttpClient, AndroidHttpClient, DefaultHttpClient,会发现有一个专门为Android应用准备的实现类AndroidHttpClient,当然使用常规的DefaultHttpClient也可以实现功能。
从两个类包所有在位置就可以看出区别,AndroidHttpClient定义在android.net.http.AndroidHttpClient包下,属于Android原生的http访问,而DefaultHttpClient定义在org.apache.http.impl.client.DefaultHttpClient包下,属于对apche项目的支持。而AndroidHttpClient没有公开的构造函数,只能通过静态方法newInstance()方法来获得AndroidHttpClient对象。

②实现

i>创建代表客户端的HttpClient对象。HttpClient client
ii>创建代表请求的对象。

HttpGet get,HttpPost post

注:对于发送请求的参数,GET和POST使用的方式不同,GET方式可以使用拼接字符串的方式,把参数拼接在URL结尾;POST方式需要使用setEntity(HttpEntity entity)方法来设置请求参数。
iii>调用HttpClient对象的execute(HttpUriRequest request)发送请求,执行该方法后,将获得服务器返回的HttpResponse对象。服务器发还给我们的数据就在这个HttpResponse相应当中。

HttpResponse response = client.execute(post)
HttpEntity entity = response.getEntity()

得到数据流:

InputStream inputStream = entity.getContent();

最后关闭过期连接。
iv>检查相应状态是否正常。服务器发给客户端的相应,有一个相应码:相应码为200,正常;相应码为404,客户端错误;相应码为505,服务器端错误。
v>获得相应对象当中的数据

3)OkHttp

网络请求框架,可通过第三方依赖导入。
包括Get 请求、Post 请求、上传下载文件、上传下载图片等功能。

4)Volley

网络请求框架,可通过第三方依赖导入。

5)android网络连接—主线程连接错误

无论是socket连接还是http连接,不应该在主线程中进行,否则会报错:android.os.NetworkOnMainThreadException。
正确的做法是:在异步任务或者新开子线程用于连接。

6)应用

检查当前网络是否可用

public class NetWork {

    /**
     * 检查当前网络是否可用
     *
     * @param context
     * @return
     */

    public static boolean isNetWork(Context context) {

        if (context != null) {
            ConnectivityManager mConnectivityManager = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
            if (mNetworkInfo != null) {
                return mNetworkInfo.isAvailable();
            }
        }
        return false;
    }
}

ping不同的网络并返回网络状态

public class PingIpAddr {

	/**
	 * ping网络,ping通返回true,不通返回false
	 * @param ipAddress = "74.125.47.104"
	 * @return
	 */
	public static final boolean pingIpAddr(String ipAddress) {

		try {
			/**-c 是指ping的次数 3是指ping 3次 ,-w 100 以秒为单位指定超时间隔,是指超时时间为100秒*/
			if (null == ipAddress || ipAddress.equals("")) {
				return false;
			}
			Process p = Runtime.getRuntime().exec("ping -c 1 -w 3 " + ipAddress);
			
			if (null != p) {

				int status = p.waitFor();
				if (0 == status) {
					return true;
				} 
			}
		} catch (IOException e) {

			LogUtil.i("Log", "PingIpAddr->Fail: IOException->" + e.getMessage());

		} catch (InterruptedException e) {
			LogUtil.i("Log", "PingIpAddr->Fail: InterruptedException->" + e.getMessage());
		}
		return false;
	}
}

你可能感兴趣的:(网络与通信,java,http,学习)