1. URL
1.1 基本概念
(Uniform Resource Locator,统一资源定位符)
protocol :// hostname[:port] / path / [;parameters][?query]#fragment
protocol协议类型
指的是当前请求的协议类型,这里是https
协议,常见的协议还有如下:
- file 资源是本地计算机上的文件。格式file:///,注意后边应是三个斜杠。
- ftp 通过 FTP访问资源。格式 FTP://
- gopher 通过 Gopher 协议访问该资源。
- http 通过 HTTP 访问该资源。 格式 HTTP://
- https 通过安全的 HTTPS 访问该资源。 格式 HTTPS://
- mailto 资源为电子邮件地址,通过 SMTP 访问。 格式 mailto:
- MMS 通过 支持MMS流媒体协议的播放该资源。(代表软件:Windows Media Player)格式 MMS://
- ed2k 通过 支持ed2k(专用下载链接)协议的P2P软件访问该资源。(代表软件:电驴 格式 ed2k://)
- Flashget 通过 支持Flashget:(专用下载链接)协议的P2P软件访问该资源。(代表软件:快车) 格式 Flashget://
- thunder 通过 支持thunder(专用下载链接)协议的P2P软件访问该资源。(代表软件:迅雷 格式 thunder://
当然我们自己也可以按照需求,自己定义自己的协议名,如常用到的移动应用开发原生和webview的h5交互,我们就会自定义一个:bridge://xxxx
来交互信息。还有在iOS中外部通过URLScheme跳转到某个App,一般这个协议都是自己定义的,如跳转到微信,是weixin://
。
hostname(主机名)
是指存放资源的服务器的域名系统(DNS) 主机名或 IP 地址。有时,在主机名前也可以包含连接到服务器所需的用户名和密码(格式:username:password@hostname)。
port(端口号)
整数,可选,省略时使用方案的默认端口,各种传输协议都有默认的端口号,如http的默认端口为80。https默认443,ftp默认:21。如果输入时省略,则使用默认端口号。有时候出于安全或其他考虑,可以在服务器上对端口进行重定义,即采用非标准端口号,此时,URL中就不能省略端口号这一项。
path(路径)
eg:https://www.jianshu.com/p/f9afd709d447
- 从域名的第一个
/
开始到最后一个/
为止,是文件路径的部分。/p/
- 从域名最后一个
/
开始到?
为止,是文件名部分;如果没有?
,则是从域名最后一个/
开始到#
为止,是文件名部分;如果没有?
和#
,那么就从域名的最后一个/
从开始到结束,都是文件名部分。本例中的文件名是f9afd709d447,文件名也不是一个URL的必须部分,如果没有文件名,则使用默认文件名。默认的就是index
,default
等
parameters
百度百科:这是用于指定特殊参数的可选项。暂时没碰到
query(查询参数)
页面加载请求数据是需要的参数,用“&”符号隔开,每个参数的名和值用“=”符号隔开。
fragment(锚部分)
#开始,字符串,用于指定网络资源中的片断。例如一个网页中有多个名词解释,可使用fragment直接定位到某一名词解释。定位网页滚动的位置
1.2 URI 和 URL区别
URI(Uniform Resource Identifier,统一资源标识符)和URL(Uniform Resource Locator,统一资源定位符)的区别是,一个是表示身份,一个是表示位置的。
举个通俗的例子,可以这样理解,我们每个人都用名字,这个名字就可以看成URI,标识着我这个人。同时我们每个人都用家庭住址,通过这个住址能找到我们,这个家庭住址就相当URL。
2. http协议(超文本传输协议)
1.概念
http是通用URL,来获取数据的网络协议。它是应用层协议,因为是指定了客户端服务器,所以在传输层是基于TCP的。特点:
-
简单快速 客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
-
通用性强 HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
-
无连接 每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
-
无状态 每次处理请求都是独立的,一次搞完,没有所谓的分包之类的。如果又缺失的字段,只能全部重新请求
2.协议格式
image.png image.png2.1 http报文格式
请求报文.png 响应报文.pngHTTP消息由客户端到服务器的请求和服务器到客户端的响应组成。请求消息和响应消息都是由:
1. 开始行(对于请求消息,开始行就是请求行,对于响应消息,开始行就是状态行)
2. 消息报头(可选)
3. 空行(只有CRLF的行)
4. 消息正文(可选)组成
2.1.1开始行
对于请求消息,开始行就是请求行
,对于响应消息,开始行就是状态行
-
请求行--方法
HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。
HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。
image.png
这里重点说一下get和post方法区别:
image.png
1、GET提交的数据会放在URL之后,以?分割URL和传输数据,参数之间以&相连,如EditPosts.aspx?name=test1&id=123456. POST方法是把提交的数据放在HTTP包的Body中
2、GET提交的数据大小有限制(因为浏览器对URL的长度有限制),而POST方法提交的数据没有限制
3、GET方式需要使用Request.QueryString来取得变量的值,而POST方式通过Request.Form来获取变量的值。
4、GET方式提交数据,会带来安全问题,比如一个登录页面,通过GET方式提交数据时,用户名和密码将出现在URL上,如果页面可以被缓存或者其他人可以访问这台机器,就可以从历史记录获得该用户的账号和密码.
GET数据包
POST数据包
POST数据包.png
可以发现, POST传入的参数,会把参数放在请求报文body(请求体)中
,而GET是直接放在请求行中的url
。
-
请求行--URL
这里第一个URL的/
后面的东西 -
请求行--Version
http版本,都是http/1.1 -
请求行--CRLF
就是一行结束的标识符,就是/r/n
-
状态行--http/1.1
标识协议版本号 -
状态行--状态码
HTTP协议的状态码由3
位数字组成,第一个数字定义了响应的类别,共有5中类别:
1xx: 指示信息--表示请求已接收,继续处理
2xx: 成功--表示请求已被成功接收、理解、接受
3xx: 重定向--要完成请求必须进行更进一步的操作
4xx: 客户端错误--请求有语法错误或请求无法实现
5xx: 服务器端错误--服务器未能实现合法的请求
常见错误码:
200 OK //客户端请求成功
400 Bad Request //客户端请求有语法错误,不能被服务器所理解
401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
403 Forbidden //服务器收到请求,但是拒绝提供服务
404 Not Found //请求资源不存在,eg:输入了错误的URL
500 Internal Server Error //服务器发生不可预期的错误
503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常
2.1.2消息报头
HTTP消息报头包括通用报头
、请求报头
、响应报头
、实体报头
。
报头的组成都是: 键 + : + 空格 + 值 CRLF
。配置了这个请求或响应的基本属性
-
通用报头
通用报头
指用于所有的请求
和响应
消息,但并不用于
被传输的实体
,只用于传输的消息
。
通用报头字段名(部分) | 解释 | 示例 |
---|---|---|
Cache-Control | 用于指定缓存指令,缓存指令是单向的(响应中出现的缓存指令在请求中未必会出现),且是独立的(一个消息的缓存指令不会影响另一个消息处理的缓存机制)。请求时的缓存指令包括:no-cache(用于指示请求或响应消息不能缓存)、no-store、max-age、max-stale、min-fresh、only-if-cached;响应时的缓存指令包括:public、private、no-cache、no-store、no-transform、must-revalidate、proxy-revalidate、max-age、s-maxage. | 为了指示IE浏览器(客户端)不要缓存页面,服务器端的JSP程序可以编写如下:response.sehHeader("Cache-Control","no-cache")。这句代码将在发送的响应消息中设置普通报头域:Cache-Control:no-cache |
Connection | 表示是否需要持久连接。(HTTP 1.1默认进行持久连接)。或者指定“close”选项,通知服务器,在响应完成后,关闭连接 | Connection: keep-alive |
Date | 表示消息产生的日期和时间 | Date: Tue, 15 Nov 2010 08:12:31 GMT |
Upgrade | 向服务器指定某种传输协议以便服务器进行转换(如果支持) | Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11 |
Via | 通知中间网关或代理服务器地址,通信协议 | Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1) |
Warning | 关于消息实体的警告信息 | Warn: 199 Miscellaneous warning |
关于通用报头字段代表的含义,参考:https://blog.csdn.net/alexshi5/article/details/80379086
-
请求报头
请求报头
允许客户端向服务器端传递请求的附加信息以及客户端自身的信息。
请求报头字段名(部分) | 解释 | 示例 |
---|---|---|
Accept | 用于指定客户端接受哪些类型的响应信息。比如Accept:image/gif,表明客户端希望接受GIF图象格式的资源;而Accept:text/html,表明客户端希望接受html文本; Accept: image/gif,text/html,表明客户希望接受gif图像或html文本 | Accept: text/plain, text/html,/ |
Accept-Charset | 请求报头域用于指定客户端接受的字符集。如果在请求消息中没有设置这个域,缺省是任何字符集都可以接受。 | Accept-Charset:iso-8859-1,gb2312 |
Accept-Encoding | 请求报头域类似于Accept,但是它是用于指定可接受的内容编码。如果请求消息中没有设置这个域服务器假定客户端对各种内容编码都可以接受。。 | Accept-Encoding:gzip.deflate. |
Accept-Language | 请求报头域类似于Accept,但是它是用于指定一种自然语言。如果请求消息中没有设置这个报头域,服务器假定客户端对各种语言都可以接受。 | Accept-Language: en,zh |
Authorization | 主要用于证明客户端有权查看某个资源。当浏览器访问一个页面时,如果收到服务器的响应代码为401(未授权),可以发送一个包含Authorization请求报头域的请求,要求服务器对其进行验证 | Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
Host | (发送请求时,该报头域是必需的)主要用于指定被请求资源的Internet主机和端口号,它通常从HTTP URL中提取出来的 | HOST: restapi-test.ihaozhuo.com:82 |
User-Agent | 我们上网登陆论坛的时候,往往会看到一些欢迎信息,其中列出了你的操作系统的名称和版本,你所使用的浏览器的名称和版本,这往往让很多人感到很神奇,实际上,服务器应用程序就是从User-Agent这个请求报头域中获取到这些信息。User-Agent请求报头域允许客户端将它的操作系统、浏览器和其它属性告诉服务器。不过,这个报头域不是必需的,如果我们自己编写一个浏览器,不使用User-Agent请求报头域,那么服务器端就无法得知我们的信息了。 | user-agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Mobile Safari/537.36 |
Pragma | 它是HTTP/1.1之前版本的历史遗留字段,仅作为HTTP/1.0的向后兼容。如果所有的中间服务器都使用HTTP/1.1版本协议的话,那么直接使用Cache-Control:no-cache是最理想的,但所有的中间服务器使用的HTTP协议版本并不完全一致。因此,发送的请求会同时含有下面两个字段。 | Pragma: no-cache |
From | 该首部字段用来告知服务器使用代理的用户的电子邮件地址。通常,使用目的就是为了显示搜索引擎等用户代理的负责人的电子邮件联系方式。使用代理时,应尽可能使用该字段,但有的代理可能会将电子邮件地址在User-Agent首部字段内。 | From: user@email.com |
If-Match | 形如If-xxx这种形式的请求首部字段,都可称为条件请求,服务器接收到附带条件的请求后,只有判断指定条件为真时,才会执行请求。 | If-Match: “737060cd8c284d8af7ad3082f209582d” |
If-None-Match | 该首部字段与If-Match的作用相反。 | If-None-Match: “737060cd8c284d8af7ad3082f209582d” |
If-Modified-Since | 该首部字段用于确认代理或客户端拥有的本地资源的有效性。它会告知服务器在些字段指定的时间后资源发生了更新就处理该请求,如果请求的资源没有更新过,则返回状态码304的响应。 | If-Modified-Since: Sat, 29 Oct 2010 19:43:31 GMT |
If-Unmodified-Since | 该首部字段与If-Modified-Since的作用相反。 | If-Unmodified-Since: Sat, 29 Oct 2010 19:43:31 GMT |
If-Range | 该首部字段属于附带条件之一,它告诉服务器若指定的If-Range值(ETag值或时间)和请求资源的ETag值或时间相同时,则作为范围请求处理。否则,返回全体资源。 | If-Range:"123456" |
Max-Forwards | 通过Trace或Options的方法发送包含该首部字段的请求时,该字段以十进制整数形式指定可经过的服务器最大数目。服务器在往下一下服务器转发请求之前,会将该首部字段的值减1后重新赋值。当值为0时,请求不再进行转发,而是直接返回响应 | Max-Forwards: 10 |
Proxy-Authorization | 客户端接收到从代理服务器发送过来的认证质询时,客户端会发送包含该首部字段的请求,以告知服务器认证所需要的信息。 | Proxy-Authorization: Basic dGlwOjkpNLAGfFY5 |
Range | 客户端发送带有该首部字段的请求可以指定服务器资源的范围。接收到该首部字段的服务器,会在处理请求之后返回状态码为206 Partial Content的响应,如果无法处理该范围请求,则会返回状态码为200 OK的响应及全部资源。 | Range: bytes=500-999 |
Referer | 先前网页的地址,当前请求网页紧随其后,即来路 | Referer: http://www.zcmhi.com/archives/71.html |
TE | 该首部字段会告知服务器客户端能够处理响应的传输编码方式以及相对优先级,它和Accept-Encoding的功能很像,但是TE只是用于传输编码。首部字段TE除指定传输编码之外,还可以指定伴随trailer字段的分块传输编码的方式。这时需要把trailers赋值给该字段值。如下所示:TE: trailers | TE: trailers,deflate;q=0.5 |
Cookie | HTTP请求发送时,会把保存在该请求域名下的所有cookie值一起发送给web服务器。 | Cookie: $Version=1; Skin=new; |
-
响应报头
响应报头允许服务器传递不能放在状态行中的附加响应信息,以及关于服务器的信息和对Request-URI所标识的资源进行下一步访问的信息。
响应头字段名(部分) | 解释 | 示例 |
---|---|---|
Server | 响应报头域包含了服务器用来处理请求的软件信息,标识服务器那边的一些信息。与User-Agent请求报头域是相对应的。 | |
Location | 响应报头域用于重定向接受者到一个新的位置。Location响应报头域常用在更换域名的时候。 | |
WWW-Authorization | 响应报头域必须被包含在401(未授权的)响应消息中,客户端收到401响应消息时候,并发送Authorization报头域请求服务器对其进行验证时,服务端响应报头就包含该报头域。 | WWW-Authenticate:Basic realm="Basic Auth Test!" //可以看出服务器对请求资源采用的是基本验证机制。 |
-
实体报头
请求和响应
消息都可以传送一个实体。一个实体由实体报头
域和实体正文
组成,但并不是
说实体报头域和实体正文要在一起发送,可以只发送实体报头域
。实体报头定义了关于实体正文(eg:有无实体正文)和请求所标识的资源的元信息。
实体报头字段名(部分) | 解释 | 示例 |
---|---|---|
Content-Type | 指明发送给接收者的实体正文的媒体类型 | Content-Type:text/html;charset=ISO-8859-1 或 Content-Type:text/html;charset=GB2312 |
Content-Encoding | 实体报头域被用作媒体类型的修饰符,它的值指示了已经被应用到实体正文的附加内容的编码,因为要获得Content-Type报头域中所引用的媒体类型,必须采用相应的解码机制。Content-Encoding这样用于记录文档的压缩方法 | Content-Encoding:gzip |
Content-Language | 资源所用的自然语言。没有设置该域则认为实体内容将提供给所有的语言阅读者。 | |
Content-Length | 实体报头域用于指明实体正文的长度,以字节方式存储的十进制数字来表示 | |
Last-Modified | 用于指示资源的最后修改日期和时间 | |
Expires | 实体报头域给出响应过期的日期和时间。为了让代理服务器或浏览器在一段时间以后更新缓存中(再次访问曾访问过的页面时,直接从缓存中加载,缩短响应时间和降低服务器负载)的页面,我们可以使用Expires实体报头域指定页面过期的时间。 | eg:Expires:Thu,15 Sep 2006 16:23:12 GMT |
2.1.3 单独的空行(只有CRLF的行)
标识报文头的结束
2.1.4 实体正文
实体正文可有可无,取决于你的请求响应的类型,如GET请求,请求报文就没有实体正文,POST请求就有。还有响应报文也可能没有实体正文,如状态码status:401请求未经授权。这时候就只有响应头,而没有实体正文。
3.HTTPS
3.1,基本概念
基于HTTP协议,通过SSL或TLS提供加密处理数据、验证对方身份以及数据完整性保护。其中TLS升级版的SSL。是为网络通信数据完整性的一种安全协议。TLS与SSL在传输层对网络连接进行加密。
分层.png
SSL协议位于TCP/IP协议与各种应用协议之间
SSL(Secure Socket Layer),为Netscape所研发,用以保障在Internet上数据传输的安全,利用数据加密技术,可确保数据在网络上的传输过程中不会被截取及窃听。
SSL由从前的网景公司开发 有1.0,2.0,3.0三个版本,但现在只使用版本3.0。TLS是SSL的标准化
后的产物
有1.0 1.1 1.2三个版本,默认使用1.0,TLS1.0和SSL3.0几乎没有区别。事实上我们现在用的都是TLS,但因为历史上习惯了SSL这个称呼,平常还是以SSL为多。
3.2 对称加密/非对称加密
3.2.1 对称加密
同一个密钥
可以同时用作信息的加密和解密,这种加密方法称为对称加密。类似我们自然使用的锁和钥匙的关系,一把钥匙可以上锁也可以开锁。
优点:对称加密算法的是算法公开、计算量小、加密速度快、加密效率高。
缺点:对称加密算法的缺点是在数据传送前,发送方和接收方必须商定好秘钥,然后使双方都能保存好秘钥。其次如果一方的秘钥被泄露,那么加密信息也就不安全了。另外,每对用户每次使用对称加密算法时,都需要使用其他人不知道的独一秘钥,这会使得收、发双方所拥有的钥匙数量巨大,密钥管理成为双方的负担。
3.2.2 非对称加密
和对称加密相对,就是加密解密不在通过同一把钥匙,而是两把,一个公钥,一个私钥,他俩是一对!
很明显公钥是给别人用的,私钥是给自己用的。
A和B通信,A生成一对密钥公钥
和私钥
,A把公钥
给B,自己留有私钥
。这时候如果B给A发消息,就用A给B的公钥
加密,A收到消息后,就可以用自己的那个私钥
解密,就知道B给A发送的消息是啥了。
常见非对称交密算法:RSA
3.3 CA机构
CA机构是什么?CA机构就是SSL证书审核签发机构,电子商务交易中备受信任的第三方,承担检验公钥体系合法性的责任。
就是一些受信任的第三方机构,类似于公证处,如果我们的网站在那边公正过,他就给我发颁发数字证书CA。证书中包含了一个密钥对(公钥
和私钥
)和所有者识别信息。数字证书被放到服务端,具有服务器身份验证和数据传输加密功能。�
3.4 Https传输过程
https访问的过程.png方便理解过程简化了,但基本流程是不变的,只是证书校验和对称加密的密钥生成方式复杂化的问题。具体过程参照https://mp.weixin.qq.com/s/UiGEzXoCn3F66NRz_T9crA。
1, 客户端访问服务端,地址是https的网址
2, 服务端必须要有一套CA数字证书,可以自己制作,也可以向组织申请。自己制作的,也可以通过https访问,但是会显示不信任
,有的浏览器会弹框。正规CA机构申请的,就是可信任的!
3,服务端有了一个可信任的CA证书,就有了一个SSL公钥(CA公钥)
,一个SSL私钥(CA私钥)
。一般在服务器配置支持https的时候,这两个密钥都需要配置。当客户端前来访问的时候,服务器就会先把CA证书/CA公钥
发送给客户端。
4, 客户端解析证书,这部分工作是由客户端的TLS来完成的,首先会验证证书是否有效,比如颁发机构,过期时间等等,如果发现异常,则会弹出一个警告框,提示证书存在问题。如果证书没有问题,那么就生成一个随机值
比如123456作为一个明文密钥。然后用CA公钥
证书对该123456这个明文密钥进行加密得到密文密钥:abcde。
5, 客户端发送密文密钥abcde给服务端。
6, 服务端的到密文密钥abcde,就用CA私钥
对其进行解密,就可以得到明文密钥:123456,用明文密钥加密要发送的内容。可见:密钥的传递用的是非对称加密。
7,客户端收到这个内容,因为自己有密码:123456,就直接可以进行解密,得到正确的内容。 可见:内容的传递用的是对称加密。
3.5 怎么保证保证服务器给客户端下发的公钥是真正的公钥,而不是中间人伪造的公钥呢?
中间人模式.pngCharles抓包工具能抓到https的包,就是利用了这个原理,配置了自己的一个CA证书,通信的时候客户端代理Charles上,Charles作为中间人转发我们的信息!
那如何防止了?这里就有了双向验证
如上,Charles之所以能抓包,那是它伪装成了真正的客户端,这个真正的客户端和服务端通信,而我们的客户端是从Charles那边拿到的信息。如果我们想杜绝这种情况,就需要不仅对服务端进行校验,还需要对客户端进行校验。
所以:双向验证本质上和单向验证没区别,上面的单向认证是客户端 check 服务端
是否合法。双向就是服务端 同时 check 客户端
是否合法。
以下是引用内容https://mp.weixin.qq.com/s/UiGEzXoCn3F66NRz_T9crA:
1、单向验证中,如果是你客户端,你需要拿到服务器的证书,并放到你的信任库中;如果是服务端,你要生成私钥和证书,并将这两个放到你的密钥库中,并且将证书发给所有客户端。
2、双向验证中,如果你是客户端,你要生成客户端的私钥和证书,将它们放到密钥库中,并将证书发给服务端,同时,在信任库中导入服务端的证书。如果你是服务端,除了在密钥库中保存服务器的私钥和证书,还要在信任库中导入客户端的证书。
3、再次强调,使用单向验证还是双向验证,是服务器决定的。
4、https的验证过程,不管是单向还是双向,只有四步,网上很多关于https验证过程的文章中,写了来来回回七八上十步。要真是这样,访问一个https地址,时间全花在了交互上了。
注意:
1,双向验证,只是对客户端身份进行验证,验证过程和客户端验证服务端的原理过程类似
2,客户端如何标识自己的身份是合法的了,也需要配置证书,生成公钥,私钥。这个证书在服务器那边也是授信的,做到这一点,iOS开发中我们一般把服务器的证书给down下来导入到本地。也可以自己配置一个新的证书,然后到处p12文件,让服务器那边信任这个证书。
根据网络资源总结,有纰漏,请指正,谢谢!
参考:
https://blog.csdn.net/xiaoming100001/article/details/81109617
https://mp.weixin.qq.com/s/UiGEzXoCn3F66NRz_T9crA
网友评论