目录
1xx:表示临时响应并需要请求者继续执行操作的状态代码。初始化
3xx:表示要完成请求,需要进一步操作。通常,这些状态代码用来重定向。(资源重定向)
4xx:这些状态代码表示请求可能出错,妨碍了服务器的处理。客户端错误
5xx:这些状态代码表示服务器在尝试处理请求时发生内部错误。这些错误可能是服务器本身的错误,而不是请求出错。代码说明
一、请求问题
一、跨域
1.跨域是指一个域下的js脚本或者文档试图请求另一个域下的数据,
2.非同源是指两个地址之间,只要协议号,IP地址,和端口号,有一个不同就是非同源,
3.浏览器的同源策略是指浏览器会拦截跨域请求,防止非同源的网页进行传递数据,
二、解决跨域问题
1.jsonp解决跨域
jsonp,利用script等标签src属性没有跨域限制来进行发送请求解决跨域问题,设置src的值为请求地址,需要把前端的回调方法传递给服务器,然后把后端准备好的数据作为回调函数的参数,返回给客户端,客户端就会调用回调函数,回调函数的参数就是响应数据,jsonp只支持get请求,jsonp这种方式没有官方的方法和规定,容易被替代。
2.cors解决跨域
暴力解决,在app.js里面导入cors模块,配置 app.use(cors()),此种方法可以解决所有的跨域问题,
单个解决,在接口中,使用cors中间件,可以解决单个接口的跨域问题,
3.设置黑白名单,把允许请求的IP地址添加到一个数组里,通过req.headers.origin 获取发送请求的IP地址, 如果当前请求的ip地址在白名单里就往当前请求头里添加请求允许控制源。 res.header("Access-Control-Allow-Origin",req.headers.origin)
4.设置代理服务器进行跨域 浏览器先给本地服务器发请求,本地服务器再向目标服务器发请求,目标服务器先把数据返回给本地服务器,本地服务器拿到数据之后会把数据再转发给客户端。在这个过程当中请求的次数有俩次,响应的次数也是2次的,以后在项目开发的时候,开发阶段需要配置代理服务器,部署的时候不需要,
设置代理服务器的步骤
// 公共资源的路径
publicPath:"./",
// 打包之后的路径
outputDir:"dist",
// 打包的首页
indexPath:"index.html",
pages:{
// 打包之后的页面配置
index:{
// 打包的入口文件
entry:"src/main.js",
// 打包的模板
template:'public/index.html',
// 打包之后的页面
filename:"index.html",
title:"斗鱼"
}
},
lintOnSave:false,
devServer:{
// 启用压缩,打包之后代码压缩
compress:true ,
port:9000,
host:"localhost",
open:true,
hot:true,// 支持热更
proxy:{
'/myApi':{
target:baseURL+'/api/RoomApi',
ws:true,//是否支持websocket
changeOrigin:true,
pathRewrite:{//路径从写,
"^/myApi":""
}
}
}
}
三、ajax
1.原理,ajax是一个xml和html的技术栈,前端用来发送请求,ajax的工作原理是在服务器和客户端之间加入一个ajax引擎,使得请求异步化,主要组成部分由JavaScript、XMLHTTPRequest、DOM对象组成,通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据, 然后用JavaScript来操作DOM而更新页面。这其中最关键的一步就是从服务器获得请求数据,
2.基础步骤
//1 创建一个请求对象
var xhr = new XMLHttpRequest()
// 2 指定网络地址进行发请求
// GET:把请求参数拼接在路径之后,
xhr.open("GET","book.xml")
// 3发送请求 ,如果是post请求的,请求参数就是在send进行发送,get请求send就不用写参数
xhr.send()
// 4拿数据onreadystatechange 在请求过程如果请求状态发生变化的时候触发
// readyState===4服务器把数据给客户端了 ,客户端可以使用了
// status===200 请求成功了
xhr.onreadystatechange = function(){
if(xhr.readyState===4&&xhr.status===200){
console.log(xhr.responseText) // 把数据返回一个字符串的格式
}
}
//2、jq对ajax的封装
// ajax请求 参数一个对象
$.ajax({
url:"http://open.douyucdn.cn/api/RoomApi/live?offset=0&limit=30", //请求url
type:"GET" ,//请求类型
data:{} ,//post请求参数需要写在data字段上
success:function(res){ // 请求成功的字段
console.log(res)
},
error:function(err){ //请求失败的回调
console.log(er)
}
})
3.ajax的优缺点
//1.ajax的优点,
ajax,能实现局部刷新页面,即在不刷新整个页面的前提下与服务器进行通信维护数据,这使得web响应更迅捷,用户体验良好
ajax,是异步通信,不需要打断用户操作,响应更迅捷
ajax,AJAX可以把以前一些服务器负担的工作转嫁到客户端,可以减轻服务器的压力
ajax,支持广泛不需要下载浏览器插件或者小程序,但需要客户允许JavaScript在浏览器上执行。
ajax,界面和应用分离,也就是数据和呈现分离,便于分工合作,和维护
//2.ajax的缺点
因为ajax是局部刷新,所以Back和History功能不能使用,即破坏了浏览器的机制,返回上一页功能不能使用,Gmail下可以解决这个问题
因为ajaxajax技术就如同对企业数据建立了一个直接通道,所以数据和逻辑有暴露的风险
ajax不能很好的支持移动设备,而且违背了url和资源定位的初衷,即采用ajax技术两个url显示的可能不相同,另外ajax会破坏程序处理机制,如Ajax.dll,Ajaxpro.dll,
ajax对搜索引擎的支持比较弱。如果使用不当,AJAX会增大网络数据的流量,从而降低整个系统的性能。
四、axios
axios是对ajax的二次封装,他是局域promise的,所以可以使用promise的API,
axios有以下特点,
1.异步局部刷新,
2.可以设置请求拦截和响应拦截,处理超时请求,取消请求
3.自动转换json数据,在node.js发送http请求
=========================================================
二次封装axios
// 本文件对axios的二次封装,有的请求需要携带token,、可以把token携带的操作放在请求拦截的函数,也就是在发请求时候,先经过请求拦截追加token发给服务器,也可以对服务器响应进行进行优化再返回给客户端 可以设置请求的服务器地址,也可以设置超时时间等。
import axios from "axios"
// 主要使用用来把前端发来的请求参数是对象结构转成url拼接的方式,防止服务器对对象这种格式请求数据取不到的情况
// 把这种格式{one:10} 转成one=10这种格式
import qs from "qs"
import { Loading } from 'element-ui';
let loadingInstance;
// 添加功能1 根据环境设置不同服务器地址
switch (process.env.NODE_ENV) {
case "production":
axios.defaults.baseURL = "http://pc.huacaijia.com"
break;
case "development":
axios.defaults.baseURL = "/myapi"
break;
default:
break
}
//功能2 添加超时功能 设置超时时间
axios.defaults.timeout = 30000 //30s
// 功能3 添加需要登路验证
axios.defaults.withCredentials = true
// 功能4 设置请求请求内容的编码格式
axios.defaults.headers["Content-Type"] = "application/x-www-form-urlencoded" //设置请求内容类型
// 请求数据进行转换 转换通过qs第三方进行转换
// data就是请求参数
// 功能5
axios.defaults.transformRequest = data => qs.stringify(data)
// 功能6 axios请求拦截 在发请求之前 对请求进行处理 一般对token添加到请求头里面操作
// config参数是请求头的配置选项,
axios.interceptors.request.use(config => {
loadingInstance = Loading.service();
// 请求时开始加载,target参数指定加载框显示的区域
let token = sessionStorage.getItem("token") //取出token
token && (config.headers.Authorization = token)
return config
}, error => {
return Promise.reject(error) // 返回错误
})
// 功能7 axios的响应拦截
// response 响应数据
axios.interceptors.response.use(response => {
loadingInstance.close();
return response.data //将主体返回给客户端
}, error => {
return Promise.reject(error)
})
export default axios
五、fetch
-
属于原生 js,脱离了xhr ,号称可以替代 ajax技术。
-
基于 Promise 对象设计的,可以解决回调地狱问题。
-
提供了丰富的 API,使用结构简单。
-
默认不带cookie,使用时需要设置。
-
没有办法检测请求的进度,无法取消或超时处理。
-
返回结果是 Promise 对象,获取结果有多种方法,数据类型有对应的获取方法,封装时需要分别处理,易出错。
-
浏览器支持性比较差。
六、常见请求状态码,和服务器状态码
xhr.readyState 请求状态
0:请求未初始化,还没有调用 open() 。
1:请求已经建立,但是还没有发送,还没有调用 send() 。
2:请求已发送,正在处理中(通常现在可以从响应中获取内容头)。
3:请求在处理中;通常响应中已有部分数据可用了,没有全部完成。
4:响应已完成;您可以获取并使用服务器的响应了。
服务器状态码
1xx:表示临时响应并需要请求者继续执行操作的状态代码。初始化
100继续,101切换协议
2xx:表示成功处理了请求的状态代码。成功
200 请求成功
3xx:表示要完成请求,需要进一步操作。通常,这些状态代码用来重定向。(资源重定向)
301(永久移动):请求的网页已永久移动到新位置。服务器返回此响应(对GET或HEAD请求的响应)时,会自动将请求者转到新位置。
302(临时移动):服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
4xx:这些状态代码表示请求可能出错,妨碍了服务器的处理。客户端错误
请求出错,前端问题
403(禁止):服务器拒绝请求。
404(未找到):服务器找不到请求的网页。
408(请求超时):服务器等候请求时发生超时。
5xx:这些状态代码表示服务器在尝试处理请求时发生内部错误。这些错误可能是服务器本身的错误,而不是请求出错。代码说明
503(服务不可用):服务器目前无法使用(由于超载或停机维护)。通常,这只是暂时状态。
504(网关超时):服务器作为网关或代理,但是没有及时从上游服务器收到请求。
505(HTTP 版本不受支持):服务器不支持请求中所用的 HTTP 协议版本
七、请求的三次握手和四次挥手
三次握手和四次挥手简述
三次握手,即客户端与服务端进行的三次通信。四次挥手,就是客户端和服务端通过四次通信释放连接,也叫连接终止协议。三次握手四次挥手都为客户端主动,服务器被动。
三次握手:
握手前:客户端和服务器都为closed状态,
第一次握手:客户端向服务器发送syn报文,客户端变为SYN_SENT,服务器变为lisent状态
第一次报文内容:syn=1 seq=x
第二次握手:服务器向客户端发送syn报文,服务器变为SYN_RECV,给服务器响应,客户端收到响应后变为ESTABLISHED状态,此时,服务器确定自己收发消息正常,
第二次报文内容:
SYN=1,ACK=1,
|
第三次握手:客户端发送ACK报文,服务器收到后变为ESTABLISHED状态,三次握手之后就可以正常收发数据,
第三次报文内容
ACK=1,seq=x+1,ack=y+1 |
因此客户端发送一个ACK报文,ack仍为序列号+1,即y+1,初始序列号为x,因此客户端发送的第二次报文,序列号要+1,即x+1;这时服务器可以确认客户端收发能力正常;第三次握手可以携带数据。
四次挥手
刚开始客户端和服务器端都处于ESTABLISHED状态,假如客户端发起关闭请求;
第一次挥手:客户端向服务器发送FIN报文(FIN=1,seq=u),发完后进入FIN_WAIT_1状态,即主动关闭TCP连接,不再发送数据,但可以接收服务器发来的报文,等待服务器回复;
第二次挥手:服务器接到FIN报文后,返回一个ACK报文(ACK=1,ack=u+1,seq=v),表明自己接收到此报文,服务器进入CLOSE_WAIT关闭等待状态,此时客户端就知道服务端接到自己的断开连接请求,进入到FIN_WAIT_2状态,TCP处于半关闭状态,但服务器端可能还有数据要传输。
第三次挥手:服务器关闭客户端连接,发送FIN报文(FIN=1,seq=w,ack=u+1)给客户端,此时服务器处于LAST_ACK状态,等待客户端回应。
第四次挥手:客户端收到FIN报文后,发送一个ACK(ACK=1,ack=w+1,seq=u+1)给服务器作为应答,此时客户端处于TIME_WAIT状态,这个状态是为了等待足够的时间以确保TCP接收到连接中断请求的确认。
注意:这时服务器到客户端的TCP连接并未被释放,客户端需要经过等待2MSL(MSL表示一个报文的来回时间)后才会进入CLOSED状态,这样做的目的是确保服务器收到自己的ACK报文,如果在规定时间没有收到客户端发的ACK,那么服务器会重发FIN,客户端再次收到FIN报文,就知道自己的ACK丢了,然后会重发ACK给服务器。服务器收到ACK后,就会关闭连接,处于CLOSE状态了。