关键字:
一问一答
用于和服务器交互
什么是HTTP
HTTP是个应用层协议,是HTTP客户端和HTTP服务器之间的交互数据格式。所以这里有个实例:在浏览网页的时候,浏览器会向服务器发送一个HTTP请求,告诉服务器我想访问什么..然后服务器会根据请求计算出HTTP响应(一般不止一个)让浏览器接收,里面包括了CSS、JS、HTML等信息。
通过浏览器的开发者工具Network栏可以监视到相关的http信息。
HTTP协议格式
通过抓包工具获取一个http数据包可以看到HTTP请求为:
POST https://weibo.com/ajax/feed/reportTipsAd HTTP/1.1 Host: weibo.com Connection: keep-alive Content-Length: 75 server-version: v2023.01.13.2 sec-ch-ua: "Not?A_Brand";v="8", "Chromium";v="108", "Microsoft Edge";v="108" DNT: 1 X-XSRF-TOKEN: ke6hGT9aa3M23Vs_oSOJtuhC traceparent: 00-d4b51744c9ffb7f50fc79b3483b66bd6-2f7c1a70cebae691-00 sec-ch-ua-mobile: ?0 client-version: v2.37.31 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.76 Content-Type: application/json;charset=UTF-8 Accept: application/json, text/plain, */* X-Requested-With: XMLHttpRequest sec-ch-ua-platform: "Windows" Origin: https://weibo.com Sec-Fetch-Site: same-origin Sec-Fetch-Mode: cors Sec-Fetch-Dest: empty Referer: https://weibo.com/u/3235322060/home?topnav=1&wvr=6 Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6 Cookie: SUBP=0033WrSXqPxfM725Ws9jqgMF55529P9D9W5w1ynisFsDgViNmPqUd4E55JpX5KMhUgL.FoeEe0-0eoz7So52dJLoI7ySqPxXwgp4I5tt; SINAGLOBAL=786663887818.4773.1668729189177; SSOLoginState=1673408840; XSRF-TOKEN=ke6hGT9aa3M23Vs_oSOJtuhC; _s_tentry=weibo.com; Apache=2034831546041.4402.1673442465212; ULV=1673442465311:6:3:1:2034831546041.4402.1673442465212:1672998500749; ALF=1676380519; SCF=Aj2UkZGnUix87JONpJqrZn0Toq8qM6i-dM6IiBr3QcprB49616dFYaZWx80jufhYLiYYqPv7Dnup3VUhqzu61lI.; SUB=_2A25Ox4w6DeRhGeVM6FcS8izMzTyIHXVttPryrDV8PUNbmtANLVbakW9NTKbpK3VFtYovwqJ53RHKTm_SN9PuqC2p; WBPSESS=j5bVwsPyplgKhEqeOaEJABifqr1gMuMEvdcTvKzYEYF9Crylrt-5KEjYodjmTRGFlaHxj5VvZYmvuO4s6glrEgwpYR-DwzSLTLDMoJbJppv65uZ2vwW3BFOVGvOJhVKLt2iYbrQNfhFGyLcOY2ZAig==
{"posid":"pos60e2a7e96ddb1","adid":"ad_63c28d711f227","page":"home","pv":1} |
包含:
首行: [方法] + [url] + [版本]
Header: 请求的属性(每组属性之间使用\n分隔) / 冒号分割的键值对(遇到空行表示Header部分结束)
Body: 空行部分内容都是Body, Body允许使用空字符串. 假如Body存在则Header中会有一个Content-Length属性来标识Body的长度
HTTP响应为:
HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 Content-Length: 33 Connection: keep-alive Server: Weibo API Gateway Date: Sun, 15 Jan 2023 13:15:23 GMT Vary: Origin Access-Control-Allow-Origin: https://s.weibo.com Access-Control-Allow-Credentials: true X-Log-Uid: 3235322060 x-frame-options: SAMEORIGIN x-xss-protection: 1; mode=block x-content-type-options: nosniff x-download-options: noopen x-readtime: 18 PROC_NODE: mapi-weibopro-node-bypass-698985b8f6-tg2ll SSL_NODE: mweibo-sslv6-003.dbl.intra.weibo.cn LB: 111.13.225.93 X-Wag-Info: bWFwaV9m
{"code":100000,"msg":"ok","ok":1} |
包含:
首行: [版本号] + [状态码] + [状态码解释]
Header: 和请求的规则一样
Body: 和请求的规则一样, 但是通常而言请求的Body不会很长的, 而假如服务器返回了一个htnl页面, 那么html的内容就是在body中.
空行的作用
HTTP协议没有规定有多少个键值对, 所以空行就自然作为一个"报头结束标记"了
HTTP(3.0版本之前)都是依赖TCP的, 没有空行就会发生粘包问题(TCP字节流嘛, 没有长度限制, 所以需要一定的标识符来声明什么时候才读取完一段数据).
HTTP中的内容
URL
Uniform Resource Locator, 唯一资源定位符, 用于找到网络上的资源, 还有一个概念叫URI, 叫唯一资源标识符, 用于区分网络上的资源, 这两者很相似, 平时不会做显示区分.
URL的格式通常为: [协议方案名] + [认证信息] + [服务器地址] + [服务器端口号] + [带层次的文件路径] + [查询字符串] + [片段标识符]
如:
https://www.bilibili.com/?spm_id_from=333.999.b_696e7465726e6174696f6e616c486561646572.1 |
协议方案名: 如http \ https \ jdbc:mysql
可省略,省略后默认是http://
认证信息: 以前可能会有user:pass这样的账号密码信息在URL中明文传输, 现在好像基本已经没有了
可省略
服务器地址: 服务器地址的形式应该为IP地址, 例子中的www.bilibili.com是一个域名, 通过DNS系统解析后可以看到其具体的IP地址
可省略,假如是HTML页面的话,省略后表示服务器的ip/域名和当前html所属的相同
服务器端口号: 关联到服务器的进程端口.
可省略,http默认端口号是80, https默认是443
带层次的文件路径: 通过文件路径来查找信息
可省略,省略后相当于/.,有些服务器会在发现路径的时候自动访问/index.html(主目录,默认打开的画面)
查询字符串: 就是一个键值对结构, 键值之间通过=连接, 键值对之间通过&分隔2
可省略
通过程序员自约定的键值对形式来告诉服务器我们需要什么样的信息
片段标识符: 通常用来标记浏览到网页的哪个片段, 下次访问的时候可以直接定位
通过cmd的ping命令可以查看域名的IP地址
p.s. 因为/?:这样的字符在HTTP的格式中已经被占用,假如报文中还有这样的字符出现就需要通过URL encode转译成 [%] + [两位16进制] 的形式(中文等同理)。如“我”就是%E6%88%91
方法Method
方法如上图
HTTP中的方法和Java中的方法概念不同,这里的方法更像是一个标识符,用的最多的就是GET和POST。
GET
GET是表示请求,用于获取服务器中的资源。如在浏览器中输入一个URL时,浏览器就会发送一个方法为GET的HTTP请求到服务器中;HTML中的link、href、img、script都会触发GET(点击后触发,然后从服务器中获取相关资源)
POST
POST和GET貌似没有本质的区别,区别可能是在应用场景上吧,在用户提交输入的数据给服务器(如登录页面)时候多有POST。通过HTML中的form标签、JS的ajax也可以构造POST请求。
GET和POST的区别
应用场景区别:GET多用于获取数据,POST多用于提交数据(不绝对)
内容区别:GET的Body通常为空,数据信息通过query string查询字符串传递;POST的Body通常不为空,数据信息通过Body传送,而query string为空。(POST的Body中可以直接传输二进制数据,query string虽然无法直接传输二进制数据,但是可以针对二进制数进行url encode)
特性区别:GET通常是幂等的(标准建议实现成幂等的),POST反之。这个特性也宣告GET可以被缓存,而POST不行。(幂等即多次请求会得到相同的结果)
报头Header
HTTP中首行后的都是键值对,所以Header其实是很多对键值对的集合。常见键值对如:
Host: 表示服务器主机的地址和端口
Content-Length: 表示body中数据的长度(应该是字节为单位?)
Content-Type: 表示body中数据的格式, 如:
application/x-www-form-urlencoded: form表单提交的数据格式
multipart/form-data: form表单提交的数据格式(通常用于提交图片/文件)
application/body数据格式: 如application/json \ application/pdf 分别表示body的数据格式为json和pdf
text/body的数据格式: 如text/html \ text/css 分别表示body数据格式是HTML和CSS
User-Agent: 表示浏览器 / 操作系统的属性
Referer: 表示这个页面从那个页面跳转过来(关联广告计费)
Cookie: 存储字符串用于实现"身份标识"功能, 可能来自于网页自行通过JS写入, 也可能又服务器发来的HTTP响应中的Set-Cookie返回给浏览器进行设置的(Cookie一个应用场景是保持登录状态)
Content-Type
用于定义网页编码类型和网络文件类型,决定了浏览器以何种方式解析文件。编码就通常为UTF-8字符集,文件类型主要掌握一下三类:
常见的媒体格式类型:[text/] + [文件类型],如text/plain、text/html;[image/] + [图像类型],如image/gif、image/png、image/jpeg等
application开头的媒体格式类型:[application/] + [文件类型],如application/pdf、application/json、application/msword等
上传文件时使用的类型:multipart/form-data
更多的话其实有个对照表,需要的话就上网查吧
d
正文Body
Body的内容与Header的Content-Type密切相关
如当Content-Type为application/x-www-form-urlencoded时,内容就是query-string般的键值对:
当Content-Type为application/json时,内容就是json格式
HTTP请求
form构造
form是HTML中一个常用的标签, 可用来向服务器发送GET或者POST请求.
其中action对应context path/后的url内容
ajax构造
HTTP响应
状态码Status Code
2系 (成功状态码)
200 OK: 表示访问成功
3系 (重定向状态码)
301 Moved Permanently: 永久重定向. 当服务器收到这种响应后, 后续的请求都会被自动改成新的地址.(通过Location字段重定向)
302 Move Temporarily: 要求客户端临时重定向. 比如登录页面中登录成功后, 自动跳转页面就是一次临时重定向.
4系 (客户端错误状态码)
403 Forbidden: 表示访问被拒绝. 在没有访问权限的时候就会出现403, 比如没有登录直接尝试访问.
404 Not Found: 表示没有找到资源. 在浏览器输入URL就是为了访问服务器的某个资源, 当这个资源不存在时候就会出现404.
405 Method Not Allowed: 表示方法不支持. 服务器不一定支持所有的方法, 或者不允许用户使用某些方法.
5系 (服务器错误状态码)
500 Internal Server Error: 服务器出现内部错误. 通常在服务器崩溃时候才会出现.
504 Gateway Timeout: 服务器响应超时. 服务器负载过大导致计算响应耗时过长会出现.
注意!HTTP虽然有状态码,但这不是说HTTP是有状态的。HTTP是无状态的。
HTTP