文章目录
必背-6.axios和fetch用法
axios
1.axios是什么?
- axios官方网址:http://www.axios-js.com/zh-cn/docs/
-
axios是什么:axios是基于Promise封装的ajax库,基于这个类库发送ajax请求,默认就是基于promise管理的,核心是
XMLHttpRequest
- ==axios基于请求方式分为了:
get/head/delete/opations/post/put/patch
==方法。
2.axios中GET系列的使用方法?
-
首先需要导入axios对应插件:
-
npm i axios <script src="node_modules/axios/dist/axios.min.js"></script>
-
-
get方法的创建:
axios.get([url],[config])
;对应的delete/head/opations方法都是用下面规范-
[url]:放我们请求资源的对应接口路径,不带参数
-
"http://127.0.0.1:8080/user/list"
-
-
[config]:用来配置请求信息,是一个对象类型,每个属性按照键值对的形式配置,常用8个。
- 我们配置的这些属性实际上是在给这次请求的xhr实例设置私有属性,不要以为都是在给请求头设字段。
-
baseUrl:[string]
:配置请求地址的前缀 -
params:[string/object]
:属性值可以是字符串可以是对象- 对象:会将里面属性名和属性值拼接为键值对,问号拼接到URL后面
- 字符串:无论字符串内写的是xxx,那直接在URL后面拼接为**“0=xxx”**
-
headers:[object]
:属性值是对象类型,作用同ajax中的xhr.setRequestHeader()
-
headers:{"Content-Type":application/json}
:但是在get跟Post中,Content-Type属性一般不需要咱们手动改 -
headers:{"Name":"sjh"}
:可以通过headers给请头添加我们想传的数据
-
-
timeout:[number]
:请求超时时间,数字类型但为是ms -
withCredentials:[boolean]
:默认为false,true:表示允许跨域携带资源凭证,false:表示不允许 -
responseType:[string]
:把服务器返回的结果转为对应的数据格式,默认是json
(服务器返回的结果,我们都把它转为json对象),还有其他类型:‘arraybuffer/blob/document/json/text/strem’; -
onUploadProgress:[function]
:监听文件上传进度 -
validateStatus:[function]
:里面是一个函数,函数中的return可以配置status
决定状态值在什么范围才算请求成功,默认2xx为请求成功
-
3.axios中POST系列的使用方法?
-
首先需要导入axios对应插件:
-
npm i axios <script src="node_modules/axios/dist/axios.min.js"></script>
-
-
axios中post的创建方式:
axios.post([url],[data],[config])
;对应的put/patch方法- url:字符串类型,请求的目标路径
- [data]:可以是字符串类型,可以对象类型,post中请求体的信息,如同xhr.send(),中传的数据,但一般不会传字符串。
- [config]:**对象类型,**配置请求的配置项
-
post常配置的配置项:
- 与get相同,但是没有params,因为post不同请求头传参
-
transformRequest:function([data],[headers]){return xxx}
:POST请求专用的方法,对请求主体进行格式处理- [data]获取的是axios.post()方法中的第二个参数的值,data必须是标准普通对象,我们在内部就可以给他做格式的处理,return什么,[data]请求体就会变成什么
- 比如我们的[data]传的是JSON对象格式的,但后台想要urlencoded格式的,那我们就可以用transformRequest转换一下。
-
axios中POST请求的请求主体:
- data就是请求体信息:发送之前,会在内部默认处理称为JSON字符串,再传给服务器
- 如果服务器想要的不是JSON字符串,可以将[data]值设置为服务器想要的字符串。
- 如果服务器想要的是urlencoded字符串,我们有两种方式做处理:
- 方式一:【引入Qs库】,基于Qs.stringify/parse做处理:axios.post([url],Qs.stringify(data),[config]);
- Qs.stringify(data):将对象转为urlencoded字符串
- Qs.parse(data):将urlencoded字符串转为对象
- 方式二:使用transformRequest:function ([data],[heders]){return xxx} 的方式,自行改成想要的格式。
- 方式一:【引入Qs库】,基于Qs.stringify/parse做处理:axios.post([url],Qs.stringify(data),[config]);
- data就是请求体信息:发送之前,会在内部默认处理称为JSON字符串,再传给服务器
4.axios内部做的优化?
-
axios内部做了一个非常有用的事情:根据我们传递给服务器的内容格式,自动帮我们设置请求头中的 Content-Type ,让其和传递的格式相匹配「MIME类型」
- urlencoded格式字符串 : Content-Type:‘application/x-www-form-urlencoded’
- json格式字符串 :Content-Type:‘application/json’
- FormData格式对象: Content-Type:‘multipart/form-data’
5.对象分为几大类?
- 对象类型「引用数据类型」
- 标准普通对象 object
- 标准特殊对象 Array、RegExp、Date、Math、Error……
- 非标准特殊对象 Number、String、Boolean……
- 可调用/执行对象「函数」function
6.axios做get请求时存在的三种错误情况?
- 有响应体:返回的错误对象中有状态码:response->status,没有code
-
无响应体:
-
timeout
:请求超时或被中断,没有状态码,有code属性:code:"ECONNABORTED" response:undefined
-
navigator.onLine=false
(断网)时:没有状态码,也没有code和response,只能用navigator.onLine=false
判断。
-
7.axios的get和post请求另一种写法?
axios({
method: 'get',
url:'http://127.0.0.1:9999/user/list',
params:{id:1},//重点,get方法中用params
headers:{}
}).then(res=>{
console.log(res);
})
axios({
method: 'post',
url:'http://127.0.0.1:9999/user/list',
data:{id:1},//重点,post方法中才能有data
headers:{}
}).then(res=>{
console.log(res);
})
8.axios二次封装?
-
提取公共配置:axios的二次封装就是将所有请求的公共部分提取到一个默认的js文件中,所有的请求都会遵循这个默认配置文件。
-
默认配置:axios.defaults.xxx;->xxx:是能够配置的配置项,如timeout
-
axios.defaults.baseURL = 'http://127.0.0.1:9999';//设置公共 前缀路径 axios.defaults.transformRequest = data => {//设置公共 转换请求体格式 if (isPlainObject(data)) return Qs.stringify(data); return data; }; axios.defaults.timeout = 60000;//设置公共 请求超时时间
-
-
请求/响应拦截器:axios.interceptors.request/response
-
-
单独配置:单独写的请求配置,优先级高于公共配置
9.axios的请求、响应拦截器怎么使用?
-
基于拦截器进行公共部分提取
-
请求拦截器:发生在 “配置项准备完毕” 和 “发送请求” 之间
-
响应拦截器:发生在 “服务器返回结果” 和 “业务代码自己处理 .then” 之间
-
//请求拦截 axios.interceptors.request.use(config => { // config对象包含的就是准备好的配置项,最后返回啥配置,就按照这些配置发请求 return config; });
-
//响应拦截:如果成功就将结果返回给用户,如果失败,进行处理再返回 axios.interceptors.response.use(response => { // 请求成功:把响应主体信息返回给业务层去使用 return response.data; }, reason => { // 请求失败:根据不同的失败原因做不同的提示 if (reason && reason.response) { // @1 有返回结果,只不过状态码不对 let {status} = reason.response; switch (+status) {//switch是做===比较 case 403: alert('服务器不爱搭理你~~'); break; case 404: alert('你傻啊,地址都错了~~'); break; case 500: alert('服务器开小差了~~'); break; } } else { // @2 请求超时或者中断 if (reason && reason.code === "ECONNABORTED") { alert('请求超时或者被中断了~~'); } // @3 断网 if (!navigator.onLine) { alert('当前网络出问题了~~'); } } // 统一失败提示处理完,到业务代码处,我们还是要失败的状态,这样才能继续做一些自己单独想做的失败处理 return Promise.reject(reason); });
Fetch
1.Fetch的使用?
-
ES6新增的一种API Fetch,是浏览器原生自带的,核心不是XMLHttpRequest,是基于全新的通信机制实现的[本身是基于promise管理的]
-
用法:
-
fetch('http://localhost:9999/job/list',{ method:'GET', headers:{},//请求头信息 //必须是字符串 // body:JSON.stringify({id:0})//请求体中的参数,GET/HEAD/OPtions/DELETE方法没有请求体,不能有body }).then(function(response){ console.log(response);//获取的是一个响应信息的对象,看不到真正的响应体 return response.json(); //想要获取响应体的信息,需要调用对应格式的response.xxx()方法 }).then(function(value){ console.log(value); })
-
-
注意点:
- GET/DELETE/OPTIONS/HEAD方法中不能存在body。
- fetch得到的结果是一个Promise对象,可以调用then方法PromiseResult是响应的信息,但找不到响应体信息。
- 想要获取响应体信息需要调用
result
对应数据格式的方法,比如想获取json格式的响应数据:result.json()
/result.text()
/result.formdata()
/… result.json
等格式获取方法只能使用一次,且只能有一种
2.axios和Fetch的区别?
- 相同点:他俩都是发送请求的
- 实现原理不同:axios是基于promise封装的ajax类库,fetch是ES6中浏览器原生的API
-
传参字段不同:
- axios的get请求参数放到
params
中,post请求体信息放到data
里 - fetch的get请求参数直接跟在
url
后面,post请求体信息放在body
里
- axios的get请求参数放到
- 环境支持程度:node环境中不支持fetch,需要引入node-fetch文件才能支持
- 功能差异:axios中的配置和拦截器等功能,fetch中都没有。
同源与跨域
1.如何区分是同源还是跨域?
- 浏览器默认存在的浏览器同源策略:不允许不同源获取数据。
- ==同源:==请求的url路径与请求端
协议类型、域名、端口号
,完全相同,则表示同源 - ==跨域:==只要
协议类型、域名、端口号
其中一个不一样就称为跨域
2.跨域请求在项目中的场景和意义,以及解决跨域的方案?
-
跨域请求不被允许的原因:【跨域请求就是做通行证】服务器不允许发送请求的地址访问**(origin 源地址)**,Access-Control-Allow-Origin
-
情景一:开发时候是跨域的,项目在部署上线后是同源的【现在很少了】
- 解决方案:开发时的跨域:修改服务器本地的hosts文件即可,【修改服务器本地DNS缓存】【很少用】
-
情景二:开发和部署的时候都是跨域的:比如将一个项目文件按类型分服务器部署
- 方案一:JSONP跨域请求方案【缺点:只支持Get请求】
- 方案二:CROS跨域资源共享【由服务器去配置】
- 方案三:PROXY跨域资源代理【最常用,需要前端去配置的】
- 方案四:postMessage+iframe【已经淘汰了】
3.CROS资源跨域共享如何设置跨域请求?
-
设置允许源 Access-Control-Allow-Origin:
-
res.header('Access-Control-Allow-Origin', 'http://127.0.0.1:5500'); res.header("Access-Control-Allow-Credentials", true);
-
-
*:允许所有源访问,但是由于服务器认为这样不安全,所以不允许外界携带跨域资源凭证访问(如cookie)
-
“http://127.0.0.1:8080”:指定单一源访问,允许携带