HTTP初体验
一、URI 和 URL的区别
URI强调的是给资源标记命名,URL强调的是给资源定位,但是你会发现,URL显然比URI包含信息更多,我通过URL也可以知道张三是总经理,并且我还知道了他的地址,所以大多数情况下大家觉得给一个网络资源分别命名和给出地址太麻烦,干脆就用地址既当地址用,又当标记名用,所以,URL也充当了WWW万维网里面URI的角色,但是他比URI多了一层意义,我不光知道你叫什么,我还知道你在哪里。我们在浏览器输入的都是URL,因为我们输入的目的是为了找到某一个资源,当然你输入的是URI也是没错的,因为URL也是URI。
总结:URI标记了一个网络资源,仅此而已; URL标记了一个WWW互联网资源(用地址标记),并给出了他的访问地址。
①URI:Uniform Resource Identifier,统一资源标识符
②URL:Uniform Resource Locator,统一资源定位符
③URN:Uniform Resource Name,统一资源名,是带有名字的因特网资源
URL是URI的子集,所有的URL都是URI,但不是每个URI都是URL,还有可能是URN
二、HTTP请求报文详解
HTTP请求报文组成部分(请求首行+请求头(键值对)+空行+请求体):
1、GTE请求与PSOT请求:
表单一般为post请求
超链接,回车,<img src=""> 一般为get请求
GET请求没有空行和请求体, 故所有的请求数据只能在地址传递,字符长度限制为255个字符
请求头:
---请求首行 GET /?username=lisi HTTP/1.1 ---请求头(键值对) Host: localhost:8080 Connection: keep-alive Pragma: no-cache Cache-Control: no-cache Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36 Sec-Fetch-Mode: navigate Sec-Fetch-User: ?1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3 Sec-Fetch-Site: same-origin Referer: http://localhost:8080/ Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 Cookie: Idea-9fe75ef2=629c3278-5e98-42df-bcd7-a3793e05ce41; _ga=GA1.1.1953189279.1568811220; Webstorm-739ac210=dad5cfb7-8b9c-4506-ab7a-3d0246b14609; JSESSIONID=89F6EDFA6C302D6AE62391FCEC31855A
响应头
---- 响应首行 -- 响应协议/协议版本 状态码 提示信息 HTTP/1.1 200 OK Server: Apache-Coyote/1.1 请求 Content-Type: text/html;charset=utf-8 Transfer-Encoding: chunked Date: Sat, 04 Jul 2020 09:12:39 GMT
POST有空行和请求体,所有的请求数据放在请求体中,所以能传输比较多的数据。
----请求首行 POST / HTTP/1.1 ----请求头 Host: localhost:8081 Connection: keep-alive Content-Length: 17 Pragma: no-cache Cache-Control: no-cache Origin: http://localhost:8080 Upgrade-Insecure-Requests: 1 Content-Type: application/x-www-form-urlencoded User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36 Sec-Fetch-Mode: navigate Sec-Fetch-User: ?1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3 Sec-Fetch-Site: same-site Referer: http://localhost:8080/ Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 Cookie: Idea-9fe75ef2=629c3278-5e98-42df-bcd7-a3793e05ce41; _ga=GA1.1.1953189279.1568811220; Webstorm-739ac210=dad5cfb7-8b9c-4506-ab7a-3d0246b14609; JSESSIONID=244C2C2725EAEDED4D5ACA786D9F8F21 ----请求空行 ----请求体 username=zhangsan
2、Content-Type内容类型
http://tools.jb51.net/table/http_content_type
1)、application/x-www-form-urlencoded
1)浏览器的原生form表单 2) 提交的数据按照 key1=val1&key2=val2 的方式进行编码,key和val都进行了URL转码
POST http://www.example.com HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=utf-8
title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3
2)、multipart/form-data
常见的 POST 数据提交的方式。我们使用表单上传文件时,必须让 form 的 enctype 等于这个值。
<form action="/" method="post" enctype="multipart/form-data">
<input type="text" name="description" value="some text">
<input type="file" name="myFile">
<button type="submit">Submit</button>
</form>
请求头看起来的样子
POST /foo HTTP/1.1
Content-Length: 68137
Content-Type: multipart/form-data; boundary=---------------------------974767299852498929531610575
---------------------------974767299852498929531610575
Content-Disposition: form-data; name="description"
some text
---------------------------974767299852498929531610575
Content-Disposition: form-data; name="myFile"; filename="foo.txt"
Content-Type: text/plain
(content of the uploaded file foo.txt)
---------------------------974767299852498929531610575--
首先生成了一个 boundary 用于分割不同的字段,为了避免与正文内容重复,boundary 很长很复杂。 然后 Content-Type 里指明了数据是以 multipart/form-data 来编码,本次请求的 boundary 是什么内容。
消息主体里按照字段个数又分为多个结构类似的部分,每部分都是以 --boundary 开始,紧接着是内容描述信息,然后是回车,最后是字段具体内容(文本或二进制)。
如果传输的是文件,还要包含文件名和文件类型信息。消息主体最后以 --boundary-- 标示结束。
3)、application/json
消息主体是序列化后的 JSON 字符串,这个类型越来越多地被大家所使用
POST http://www.example.com HTTP/1.1
Content-Type: application/json;charset=utf-8
{"title":"test","sub":[1,2,3]}
这种方案,可以方便的提交复杂的结构化数据,特别适合 RESTful 的接口。传递JSON字符串可以方便的让前端转为js的对象,进行显示和逻辑操作。
4)、text/xml
是一种使用 HTTP 作为传输协议,XML 作为编码方式的远程调用规范
POST [http://www.example.com](http://www.example.com) HTTP/1.1
Content-Type: text/xml
<!--?xml version="1.0"?-->
<methodcall>
<methodname>examples.getStateName</methodname>
<params>
<param>
<value><i4>41</i4></value>
</param>
</params>
</methodcall>
5)、text/html
以html的形式输出
6)、text/plain
在页面上原样显示这段代码。
2、状态响应码
http://tools.jb51.net/table/http_status_code
1xx 消息,一般是告诉客户端,请求已经收到了,正在处理,别急...
2xx 处理成功,一般表示:请求收悉、我明白你要的、请求已受理、已经处理完成等信息.
- 200 OK:客户端请求成功。
3xx 重定向到其它地方。它让客户端再发起一个请求以完成整个处理。
301 Moved Permanently:永久性重定向,表示请求的资源被分配了新的URL,之后应使用更改的URL;
302 Found:临时性重定向,表示请求的资源被分配了新的URL,希望本次访问使用新的URL;
301与302的区别:前者是永久移动,后者是临时移动(之后可能还会更改URL)
303 See Other:表示请求的资源被分配了新的URL,应使用GET方法定向获取请求的资源;
302与303的区别:后者明确表示客户端应当采用GET方式获取资源
- 304 (NOT MODIFIED): 该资源在上次请求之后没有任何修改。这通常用于浏览器的缓存机制。
4xx 处理发生错误,责任在客户端,如客户端的请求一个不存在的资源,客户端未被授权,禁止访问等。
- 400 Bad Request:表示请求报文中存在语法错误;
- 401 Unauthorized:未经许可,需要通过HTTP认证
- 403 Forbidden:服务器拒绝该次访问(访问权限出现问题
- 404 Not Found:表示服务器上无法找到请求的资源,除此之外,也可以在服务器拒绝请求但不想给拒绝原因时使用;
5xx 处理发生错误,责任在服务端,如服务端抛出异常,路由出错,HTTP版本不支持等。
- 500 Internal Server Error:服务器发生不可预期的错误。
- 503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常,举个例子:HTTP/1.1 200 OK(CRLF)。
三、Cookie和Session的区别
https://www.cnblogs.com/lingyejun/p/9282169.html
HTTP是无状态协议
- 无状态:服务器无法分辨每次请求来自谁
所以使用cookie是让浏览器去保存一份数据,以后访问的时候带上相应的数据。Cookie是服务器发给浏览器保存的
四、HTTP请求流程
上图有一个错误,请注意,是OSPF不是OPSF。 OSPF(Open Shortest Path Fitst,ospf)开放最短路径优先协议,是由Internet工程任务组开发的路由选择协议
总体来说分为以下几个过程:
- DNS解析
- TCP连接
- 发送HTTP请求
- 服务器处理请求并返回HTTP报文
- 浏览器解析渲染页面
- 连接结束
五、什么是HTTP无状态?
1、定义
HTTP无状态协议,是指协议对于交互性场景没有记忆能力。
2、例如
在点击一个纯的html网页,请求获取服务器的html文件资源时,每次http请求都会返回同样的信息,因为这个是没有交互的,每一次的请求都是相互独立的。第一个请求和第二个请求也没有先后顺序,返回处理哪个,结果都是同样的资源页面,因为这种场景是无交互的,无论是什么人请求这个地址,服务器都是返回那个相同的响应。
在无交互场景中上面那样,当然也不会有太大的问题。但是对于涉及到动态交互的场景,就显得很尴尬了,何为交互?有来又有往,对于一模一样的两个接口,不同的人在请求第二个接口时可能会基于请求第一个接口的结果而有所不同。
3、具体场景:
现在我们来想一个复杂的场景,如在购物网站上买一个书包,流程如下:
- 输入账号密码登陆 /login 用户信息
- 选择一款你喜欢的书包加入到购物车中 /cart 用户信息,产品信息
- 购买支付 /pay 用户信息,商品信息,金额信息
所谓的登录只是验证你是否是一个合法用户,若是合法则跳转到信息的页面,不合法则告知用户名密码错误。
但是我们在第一步给服务器发完/login接口后,服务器就忘记了。。。忘记了你这个人,到底有没有经过认证。
所以在添加商品时/cart 你还是需要将你的账号密码和商品信息一起提交给 addCart接口,再让服务器做验证。