文章目录
- 一. http请求
- 1. 认识URL
- urlencode
- 2. 认识方法
- 应用场景
- 构造http请求
- 2. 认识请求报头header
- 二. http响应
- 1. 状态码
一. http请求
1. 认识URL
我们所说的"网址", 其实就是URL(Uniform Resource Locator 统⼀资源定位符)
1.协议方案名
常见的有http和https, 也有其他类型(例如访问mysql用的是jdbc:mysql)
2.登录信息
现在的网站进行身份认证一般不会再通过URL进行了, 所以一般URL都会省略
3.服务器网址
此时就是一个"域名", 域名会通过DNS系统接续成一个具体的IP地址
4.服务器端口号
URL中的端口号可以省略不写, 浏览器会设置一个默认的端口, 这个端口是服务器决定的, 并不是自动分配
如果是http协议, 端口号使用80
如果是https协议, 端口号使用443
5.带层次的文件路径
描述了要访问服务器的哪个资源
一个服务器, 可以提供很多资源供外界访问
比如, 一个网站可能会包含很多不同的网页, 就可以通过这里的路径区分不同的网页了
例如:
6.查询字符串query string
本质是一个键值对结构. 键值对之间使⽤ & 分隔. 键和值之间使⽤ = 分隔
就是一些参数, 通过参数, 把一些客户端想传给服务器的数据告知过去
例如:
这些参数都市程序猿自定义的, 咱们是不清楚其中的含义的
7.片段标识
片段标识主要用于页面内跳转
urlencode
像 / ? : 等这样的字符, 已经被url当做特殊意义理解了. 因此这些字符不能随意出现
那么, urlencode就是针对query string中的value进行转义的!
例如搜索++:
‘’+''的 ascii值就是2B, 遇到需要转码的符号, 就会在ascii的基础上加上%, 这样url在见到%时, 就知道后面是需要转码的数据了
例如上述搜索的蛋糕:
虽然看上去在地址栏中是汉字, 但是如果我们复制过来, 就发现:
https://cn.bing.com/search?q=%E8%9B%8B%E7%B3%95&qs=n&form=QBRE&sp=-1&lq=0&pq=dangao&sc=10-6&sk=&cvid=E3B8267E2F4047EB81CE546B0C615A5D&ghsh=0&ghacc=0&ghpl=
如果输入的是汉字, 就会根据utf8编码结果, 在每个字节前加上%, 就是上述的效果
如果不进行转码, 直接发送http请求, 就可能导致页面会跳转失败, 没有被正确处理
2. 认识方法
我们只需要掌握两个方法即可
GET和POST
面试题: 谈谈GET和POST有啥差别?
首先, GET和POST从本质上看, 没什么差别
GET的应用场景, 使用POST也可以, POST的使用场景, 使用GET也可以
但是, 从使用习惯的角度来说, 还是有区别的
1)
GET从语义上来说, 通常用来"获取数据"
POST从语义上来说, 通常用来"提交数据"
2)
GET传递数据的时候, 通常使用query string, 不会搭配body
POST传递数据的时候, 通常使用body, 不搭配query string
3)
服务器对于GET请求的设计, 经常是设计成"幂等"的(这时只是http协议标准文档中给的建议)
而POST请求的设计, 不要求"幂等"
幂等, 就是每一次请求的结果, 每个人都是相同的
不幂等, 就是每次请求的结果是不同的, 例如哔哩哔哩, 每次刷新主页, 都是不同的
GET请求的结果可以被缓存, 可以被浏览器收藏夹收藏
POST不可以被缓存, 不能被收藏
被缓存, 是指通过GET获取到的一些图片, 浏览器就可以缓存这些图片, 下次访问这个网站的时候, 就不必从网络获取了, 直接从缓存的数据读取即可(缓存在硬盘上)
以下的几种说法都是有问题的:
- POST比GET更安全
- GET传输的数据量有限, 比较短, POST传输的数据量长, 没有限制
http标准中, 明确规定, GET的url长度是不做任何限制的- GET只能传输文本数据, POST可以传输文本, 也可以传输二进制
url中的query string中提供了urlencode机制, 通过这个机制, 二进制数据, 也是可以进行encode转义的
应用场景
网络上大部分请求, 都是GET, 通过query string告诉服务器要搜索啥, 服务器返回结果完整页面
POST的应用场景通常就两种:
1)登录
例如登录gitee, 通过抓包看到
body:
2)上传文件
假设上传一个头像
构造http请求
构造GET:
1)
在浏览器地址栏直接数据url, 此时就是GET请求, 点击收藏夹, 同理的效果
2)
网页html中可能有一些特殊的标签
img / a / link … 这些标签, 会带有一个url作为属性
网页被浏览器加载之后, 解析到这些标签, 就会根据url构造出新的http请求
3)表单
html中的特殊标签form
4)js
构造POST:
1)表单
2)js
2. 认识请求报头header
header 的整体的格式也是 “键值对” 结构, 都是标准规定的内容
每个键值对占⼀⾏. 键和值之间使⽤分号分割
我们只介绍几个常用的:
1 Host
host的value是域名, 通常和上面url的域名相同
如果url使用ip地址, 那么host还是域名
2 Content-Length 描述了body的长度(单位字节)
知道body的长度, 才能防止出现粘包问题
通过空行找到body的开始, 通过Content-Length 找到body的结束位置
3 Content-Type 描述了数据类型
传输的数据有很多种类型: 图片, 视频, 音频, 字体, html, json, css…
这些不同的类型, 服务器就会有不同的处理方式
(如果没有body, 就没有上述两个字段, 如果有body, 这两个字段必须在)
4 User-Agent (简称 UA)
表示浏览器/操作系统的属性.
UA里的信息主要是两个方面:
1)浏览器版本
2)操作系统版本
UA最主要的作用就是用来区分, 当前的设备是电脑还是手机
如果是电脑, 返回一个款的网页
如果是手机, 返回一个窄屏, 并且按钮比较大的网页
那么如果使用UA区分不同版本的网页, 意味着网站开发者就需要维护两套代码
后来, 前段发明了**“响应式布局”**, 只需要写一套代码, 这个代码能根据你设备的尺寸(宽度), 设置不同样式, 从而很好的适应各种设备
5 Referer
表⽰这个⻚⾯是从哪个⻚⾯跳转过来的
表示当前的网页是从bing跳转过来的
投放广告的广告主, 会多个渠道投放广告
用户每次点击, 把请求发到假设搜狗的服务器, 广告主同时也会收到请求
广告主就需要知道这个点击是从哪个渠道获得的
那么广告主就可以根据Referer来区分了, 如果域名是百度, 那么就是来自百度的请求…
但是, 在2015年左右, 运营商把访问服务器的请求referer给修改了, 修改成了自己的referer
正常, 运营商的广告平台可能效果一般, 本身没太多的流量, 但是通过上述的修改, 站在广告主的角度, 就觉得你们运营商这个广告平台收益很大
HTTPS就是重要的反制手段, HTTPS直接针对http请求的内容包括header进行加密, 防止运营商篡改, 从根源上, 解决了运营商劫持的问题
后来, 各个互联网公司, 纷纷升级HTTPS, 直到今天, 很少能看到纯http
6 Cookie
Cookie中, 是键值对的格式, 都是程序猿自定义的
网页, 是运行在浏览器上的, 默认情况下, 一个网页不能直接访问用户的硬盘
但是有个网站, 确实需要再客户端这边存储一些必要的信息, 希望能持久化存储(写到硬盘上, 重启也还在), 那么就蓝旗就给网页提供了特定的机制Cookie(并不是让网页直接读写你的硬盘, 而是对于硬盘操作, 做了一个特殊的封装, 相当于提供了一组特殊的文件, 只能往这个特殊的文件里写, 并且内容只能是键值对)
每个网站都有一份自己的Cookie文件
Cookie是从哪里来的?
Cookie中的数据都是来自服务器
如果是一个新的浏览器, 第一次访问某个网站, 此时这个网站对应的cookie就是空着的
服务区, 返回的http响应中, 就会包含Set-Cookie这样的header, 就会把一些键值对, 保存在浏览器的cookie中
Cookie中, 虽然键值对都是程序员自定义的, 但是往往会有一个特殊的键值对, 叫做会话ID(sessionID), 用来表示用户的身份信息
对应的服务器中, 存的就是**“会话”**, 保存了id和相关联的各种信息
Cookie到哪里去?
Cookie保存到浏览器之后, 后续浏览器访问该网站的时候, 就会在请求header中, 把之前保存的这些cookie键值对再次发送给服务器
过程:
例如, 我们在写博客的时候, 需要先登录, 登录之后, 进入了主页
此时, 服务器已经Set-Cookie, 这个登录的账号就会被保存下来
然后, 我们需要点击"发布"按钮, 页面就会跳转到写文章的网站
如果浏览器发送的请求中, 没有cookie, 那么服务器是不知道你的登录信息的, 这次可能就需要重新再登陆
但是, 如果请求中带上了Cookie, 那么服务器就会根据SessionID找到对应的Session, 就无需再次登录了
一旦Cookie中保存了这个信息, 就算是你重新打开这个网页, 也是在登录状态的
二. http响应
1. 状态码
描述了这次http请求是否成功, 以及失败的原因
http他当年还没有成熟的"异常"这样的机制去参考, 也仍然是通过状态码来表示错误形态
我们只关注几个重要的
- 200 OK
访问成功
- 404 Not Found
客户端请求的资源在服务器中不存在
这是URL, 包括了要搜索的资源路径, 如果我们修改了这个路径:
- 403 Forbidden
客户端的权限不足, 被禁止访问了
例如我们在访问gitee时, 如果访问了别人私有的库, 就会出现
- 405 Method NOT Allowed
请求的方法, 服务器不支持
比如, 服务器只实现了GET, 没实现POST, 此时你发送POST, 就可能得到405 - 500 Internal Server Error
服务器内部出现错误, 服务器代码出现bug - 504 Gateway Timeout
服务器访问超时
客户端要访问的服务器, 不止一台, 可能是很多台, 会有一个入口服务器, 就称为"网关服务器"
这种问题常出现于"服务器比较繁忙的情况" - 302 Move temporarily
临时重定向
访问某个地址的时候, 访问的是就得地址, 就会自动跳转到新的地址上
像搜狗中, 每个广告, 最终跳转到哪里, 结果都是不一定的, 不应该进行缓存 - 301 Moved Permanently
永久重定向.
访问的旧地址和新地址之间的映射关系, 就固定了, 此时浏览器就会缓存这样的结果
当浏览器收到这种响应时, 后续的请求都会被⾃动改成新的地址, 相比于302就减少了一次http请求
例如, 服务器迁移了, 域名更新了, 就可以设置成301永久重定向
除了可以通过代码的方式来构造请求之外, 还可以专门通过专业的工具来构造请求, 更简单更方便
尤其是需要一些测试类的工具