1) 概念:http是超文本传输协议,是应用层的协议,它是基于TCP/IP协议的,可能还基于了SSL协议,基于SSL协议就是https协议了。
2)原理和特性
http协议是用于客户端和服务端通信使用的,需要客户端与服务端通过(TCP)三次握手来完成连接,连接后客户端发送请求,服务端对请求作出响应。
http协议是无状态的,即每次请求之间是没有联系的,可以使用cookie-session来记录状态。
http请求时基于TCP连接的(可以说所有的http协议都是基于TCP的),一次TCP连接之后可以多次发送http请求(在http1.1中)。
http0.9 只能搭建静态网站
http1.0 奠定了http基础
http1.1
(参考https://segmentfault.com/q/1010000019503002?utm_source=tag-newest)
增加了Connection: keep-alive,可以一次TCP连接发送多次http请求,即引入了管道机制,可以在TCP连接周期内并发请求,
通常keep-alive下的一次TCP连接维持在5-15s,维持时间过长可能浪费服务器资源。
http2
多路复用:(参考:https://segmentfault.com/a/1190000011172823)
尽管http1.1增加了keep-alive,实现了一定时间内的并发访问,但仍然存在效率问题:
*串行传输。数据帧是按顺序串行传输的。
而http2引入了二进制数据帧和流的概念,对数据帧进行了编号,可以并行传输数据帧。
*连接数过多,浏览器最多可以建立6个TCP连接,这样很快就会达到服务器的并发极限,若再有人想要连接则需要排队等待。
而http2中只建立一条通道(无论多少个访问,都只有一个TCP连接)。使得更多人可以无需排队便访问。
首部压缩:压缩了首部字段,节省带宽
服务端推送:一次请求,多次响应(减少请求次数)
3)请求的结构&响应的结构
请求-------------------
开始行:请求方法 URI 协议版本号
首部行:首部字段(即请求头信息,键值对的形式)
空行
请求内容
响应-------------------
开始行:协议版本号 状态码
首部行:首部字段(响应头信息)
空行
响应内容
4)请求方法
get 获取响应内容
post 传输请求内容
put 上传文件
delete 删除文件
head 类似get,获取报文首部。要求只返回头部信息,不返回响应内容。
option 询问支持的方法,常用于复杂方法之前
简单请求和复杂请求
get,head 或是是content-type为
[text/plain | multipart/form-data | application/x-www-url-encoded]
的post请求 && 无自定义的请求头部自动 都是 简单请求; 其他都是复杂请求。
在CORS(跨域资源共享)中,复杂请求都需要先发送一个预检请求(option方法),一方面用来判断是否支持后面的请求方法,另一方面用来判断是否发生跨域以及服务器是否支持跨域。
5)状态码
1xx 处理中
2xx 成功
3xx 重定向
301 永久重定向
302 临时重定向
304 资源未修改(不是重定向)
4xx 客户端出错
400 请求报文错误(通常是请求参数错误)
401 未认证。表示用户身份不明确,注册登录后把token放在头部自动Authorization中即可通过认证。
403 无权限,禁止访问。表示服务器认可你的身份,但是你没有权限访问该资源。
404 未找到资源
5xx 服务端出错
500 服务器内部错误,程序出错(出bug了)
503 表示服务器超出负荷或者停机维修,无法处理当前请求。
504 网关超时
*主要是区分浏览器中get和post的区别,而不是在ajax中的区别!
1)get是用来获取资源的,post是用来传输请求体的
2)get的参数放在URL上,post的参数放在Request Body中
3)get请求浏览器会产生缓存,post请求不会有缓存(除非手动设置)
4)浏览器后退对get无害,但post则可能重复提交
5)get的url只支持ASCII字符
...
*get的url有限制
url长度限制,不同浏览器的长度限制不一样,长度限制在1w英文字符左右
如果参数中包含中文(url仅支持ASCII字符),需要使用encodeURI和decodeURI 编码和解码,这并不会对ASCII字符编码,只会对非ASCII字符编码。
如果参数包含= ?等一些特殊ASCII字符,则需要encodeURIComponent()来编码和decodeURIComponent()来解码。
JS发送Http请求5个步骤
// 1.创建XHR对象
const xhr = new XMLHttpRequest()
// 2.注册事件(拦截请求和响应)
xhr.onreadystatechange = function(){
// readyState含义:0表示刚创建XHR未初始化 1表示open()后, 2表示send()后, 3表示客户端正在接受数据
// 4表示接受数据完毕
if(xhr.readyState === 1){
console.log('拦截请求')
}else if(xhr.readyState === 4){
if(xhr.status === 200){
dealResponse(JSON.parse(xhr.responseText))
}else{
console.log('error: '+xhr.status)
}
}
}
// 3.设置请求方法和url
xhr.open('get', url)
// 4.发送请求
xhr.send()
// 5.处理响应
function dealResponse(data){
console.log(data)
}
封装Ajax
const ajax = {
get: function(url, succeed, fail){
const xhr = new XMLHttpRequest()
xhr.onreadystatechange = function(){
if(xhr.readyState===4){
if(xhr.status === 200 || xhr.status === 304){
succeed(xhr.responseText)
}else{
fail(xhr.responseText)
}
}
}
xhr.open('get', url)
xhr.send()
},
post: function(url,data, succeed, fail){
const xhr = new XMLHttpRequest()
xhr.onreadystatechange = function(){
if(xhr.readyState===4){
if(xhr.status === 200 || xhr.status === 304){
succeed(xhr.responseText)
}else{
fail(xhr.responseText)
}
}
}
xhr.open('post', url)
xhr.send(data)
}
}
相同点:ajax和axios都是基于XMLHttpRequest(不是fetch).
*ajax是JQuery中的东西,属于MVC时代的产物,不适合现在的MVVM开发,为了使用ajax而引入JQuery是没必要的
区别:
1)axios支持Promise,避免了地狱回调。
2)axios提供了一些并发的接口。(axios.all(), axios.race() )
3) axios可以拦截请求响应。
4) axios可以让客户端避免CSRF攻击。(token技术)