当前位置:   article > 正文

【前端请求】一文总结Ajax、Axios及Fetch_axios ajax fetch

axios ajax fetch

1.Ajax

        Ajax 全称 Asynchronous JavaScript And XML 及异步JS与XML,其主要原理是使用XMLhttpRequest对象完成前后端交互,

它通过状态码readyState区别当前状态,分别为

        0.未定义

        1.载入中

        2.载入完成

        3.交互中

        4.交互完成

可通过状态码改变执行操作,而平时使用的ajax都是封装好的一个程序,他的封装过程如下:

        1.获取请求对象,内部应当包含请求类型,接口url和上传服务器的数据 

        2.新建httpRequest对象  

let xhr = new XMLHttpRequest()

        3.将请求配置参数赋值给httpRequest对象

xhr.open('get', obj.url + toValue(obj.data), obj.isAsync)

        4.发送

xhr.send()

        5.状态更改回调检测到数据返回并执行相应操作

  1. xhr.onreadystatechange = function () {
  2. if (xhr.readyState === 4) {
  3. 解析后端返回数据
  4. }
  5. }

一个简单的ajax封装应当是这样的

        

  1. //封装一个ajax 即XMLHttpRequest
  2. /*
  3. 使用说明
  4. 以一下格式发送数据
  5. ajax({
  6. url: '/login',
  7. method: 'get',
  8. data: {
  9. username:'xh1001',
  10. password:'T01'
  11. },
  12. isAsync: 'true',
  13. success:function(res){
  14. console.log("res:",res.data);
  15. },
  16. error:function(err){
  17. console.log("err:",err);
  18. }
  19. })
  20. */
  21. /*分割线************************ */
  22. function ajax(obj) {
  23. //判断接口是否为空
  24. if (!obj.url) {
  25. return;
  26. }
  27. //1.数据检查及补充
  28. //请求种类,默认为get
  29. obj.method = obj.method || 'get'
  30. //是否异步,默认为true
  31. obj.isAsync = obj.isAsync || 'ture'
  32. //是否有数据,没有默认补充为空对象
  33. obj.data = obj.data || {}
  34. // 2.准备ajax
  35. let xhr = new XMLHttpRequest() || new ActiveXObject()//ie兼容
  36. // 发送get或者post
  37. if (obj.method === 'get') {
  38. // 准备发送数据
  39. xhr.open('get', obj.url + toValue(obj.data), obj.isAsync)
  40. // 发送get
  41. xhr.send()
  42. } else if (obj.method === 'post') {
  43. // 准备发送数据
  44. xhr.open('post', obj.url, obj.isAsync)
  45. // 配置请求头content-type 申明数据以什么方式解析数据(json)
  46. xhr.setRequestHeader('Content-type', 'application/json')
  47. // 配置请求头content-type 申明数据以什么方式解析数据(表单数据)
  48. // xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
  49. // 发送post(json)
  50. xhr.send(JSON.stringify(obj.data))
  51. // 发送post(表单数据)
  52. // xhr.send(toValue(obj.data))
  53. }
  54. // 检测readyState判断是否将数据传回
  55. xhr.onreadystatechange = function () {
  56. if (xhr.readyState === 4) {
  57. if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
  58. //返回数据已obj的success回调函数输出
  59. // console.log('====',xhr.responseText);
  60. // obj.success(JSON.parse(xhr.responseText))
  61. // obj.success(xhr.responseText)
  62. // 检测cookie,如果cookie无效将执行
  63. if (JSON.parse(xhr.responseText).code === 201) {
  64. console.log(JSON.parse(xhr.responseText));
  65. .....
  66. } else {
  67. obj.success(JSON.parse(xhr.responseText))
  68. }
  69. } else {
  70. obj.error('unknowError')
  71. }
  72. }
  73. }
  74. }
  75. //前端数据拼接为表单格式
  76. const toValue = function (obj) {
  77. let str = '?'
  78. for (let key in obj) {
  79. str += `${key}=${obj[key]}&`
  80. }
  81. return str.slice(0, str.length - 1)
  82. }

其中 // xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')这里的setRequestHeader其实是对请求头进行配置,而Content-type具体是对请求的数据解码方式进行说明,以便后端服务器处理数据,

        常用的有application/x-www-form-urlencoded(原生form表单)、application/json(json数据)、multipart/form-data(带文件上传功能得数据盒子,一个对象)

这样在页面中只要调取ajax({datas})程序 ,就可以发送ajax请求了

当然数据的处理不是一概而论的,所以我们在发送ajax时输入的对象中配置成功或失败的回调(这里只针对返回的数据而言成功与否,并不是对ajax请求)

  1. ajax({
  2. url: '/studentCodeChange',
  3. method: 'post',
  4. data: {
  5. id: nowUser.s_id,
  6. oldCode: oldCode,
  7. newCode: newCode
  8. },
  9. success: function (data) {
  10. console.log("data", data);
  11. // 清空输入框
  12. alert('修改密码成功')
  13. $('#codeChangeLab').css('display', 'none')
  14. $('#oldCode').val('')
  15. $('#newCode').val('')
  16. $('#reCode').val('')
  17. },
  18. error: function (err) {
  19. console.log('err', err);
  20. alert('查询失败,请稍后尝试')
  21. }
  22. })

2.Axios

axios本身是对ajax而言的一个二次封装,相比原生Ajax,它用到了promise技术,从而改变了ajax需要多次调用时的尴尬,在成功之后我们可以用.then().catch()轻易进行链式调用,使得代码可读性更高,同时promise可以更方便地对请求本身进行修改,从而很好地解决了身份验证,地址传值等处的代码量,我们在使用时可以简单地调用它,也可以进行复杂的逻辑操作。

        一个简答的axios请求是这样的:

  1. const axios= axios.create({
  2. baseURL: '/api', // 给axios请求的 url 前面加一个 '/api'
  3. timeout: 5000, //整体设置axios的请求超时时间
  4. // headers: {'X-Custom-Header': 'foobar'} //整个加请求头
  5. })
  6. axios({
  7. url: '/SystemSetting/login',
  8. method:'post',
  9. data: data
  10. }).then((res)=>{
  11. do sth......
  12. })
  13. axios({
  14. url: '/SystemSetting/login',
  15. method:'get',
  16. params: data
  17. }).then((res)=>{
  18. do sth......
  19. })

正如上面所说的 ,我们可以对axios进行一定的封装,通常封装的目的是

1.配置baseUrl

通常项目开发时,需要跨域,在我们设置了跨域服务器后,请求也需要向对方服务器发送,所以要配置一个变量作为请求头,而这里的baseUrl激素hi为了统一配置方便开发,开发完成后置空或者删除再部署到服务器

2.拦截器配置

axios.interceptors.request.use

3.设置延迟时间

请求不能一直等待,当到达一定时限后要取消发送并返回请求超时

  1. import axios from 'axios'
  2. const http = axios.create({
  3. baseURL: '/api', // 给axios请求的 url 前面加一个 '/api'
  4. timeout: 5000, //整体设置axios的请求超时时间
  5. // headers: {'X-Custom-Header': 'foobar'} //整个加请求头
  6. });
  7. // 以下是拦截器
  8. //拦截请求 use 接收两个参数 第一个是请求成功的回调函数,第二个请求失败的回调函数
  9. http.interceptors.request.use(function (req) {
  10. //再整整发起请求前的操作
  11. // console.log('req',req);
  12. //如果有token的话,就携带上,没有不携带
  13. if(localStorage.getItem('token')){
  14. //携带在请求里面
  15. req.headers['token'] = localStorage.getItem('token')
  16. }
  17. return req; //放行
  18. }, function (error) {
  19. // Do something with request error
  20. return Promise.reject(error);
  21. });
  22. //拦截响应
  23. http.interceptors.response.use(function (res) {
  24. //响应回来 做的操作
  25. // console.log('相应回来的数据',res);
  26. //存token
  27. if(res.data.data && res.data.data.token){
  28. localStorage.setItem('token',res.data.data.token)
  29. }
  30. //简写
  31. // res.data.token && localStorage.setItem('token',res.data.token)
  32. //判断res里面有没有token,有的话就存起来,没有就不管
  33. return res; //放行
  34. },
  35. function (error) {
  36. console.log('err111',err);
  37. //判断一下响应的状态码
  38. if(error.response.status === 401){
  39. alert('身份过期 没有携带token')
  40. //把token清除掉
  41. localStorage.removeItem('token')
  42. //跳转到等录取 重新验证身份
  43. }
  44. return Promise.reject(error);
  45. }
  46. );
  47. export default http

3.fetch

fetch是基于promise的一个原生语法糖,关于他的用法,官方给出了一个很完善的例子

  1. // Example POST method implementation:
  2. async function postData(url = '', data = {}) {
  3. // Default options are marked with *
  4. const response = await fetch(url, {
  5. method: 'POST', // *GET, POST, PUT, DELETE, etc.请求方式
  6. mode: 'cors', // no-cors, *cors, same-origin 是否开启代理
  7. cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached缓存
  8. credentials: 'same-origin', // include, *same-origin, omit是否同源
  9. headers: {
  10. 'Content-Type': 'application/json'数据类型
  11. // 'Content-Type': 'application/x-www-form-urlencoded',
  12. },
  13. redirect: 'follow', // manual, *follow, error重定向
  14. referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
  15. body: JSON.stringify(data) // body data type must match "Content-Type" header同请求头
  16. //格式
  17. });
  18. return response.json(); // parses JSON response into native JavaScript objects
  19. }
  20. postData('https://example.com/answer', { answer: 42 })
  21. .then(data => {
  22. console.log(data); // JSON data parsed by `data.json()` call
  23. });

一般使用的时候还是要封装,我们再举一个简单的封装案例:

  1. function http({url,method,data={},headers={}}){
  2. console.log(method)
  3. console.log(data)
  4. if(!url){
  5. return
  6. }
  7. // 常用请求头
  8. headers["Content-type"] = "application/json"
  9. headers["token"] = "token@@@@@"
  10. if(method.toLowerCase()==="get"){
  11. data = JSONtoUrl(data)
  12. console.log("getting")
  13. let newUrl = url+'?'+data
  14. let init = {method:"get"}
  15. return fetch(newUrl,init).then((res)=>{res.json()})
  16. }else{
  17. console.log("posting")
  18. let init = {
  19. method:"post",
  20. body:JSON.stringify(data),
  21. headers
  22. }
  23. console.log(init)
  24. console.log(init.body)
  25. return fetch(url,init).then((res)=>{res.json()})
  26. }
  27. }
  28. function JSONtoUrl(json){
  29. let str = ''
  30. for(let k in json){
  31. str += `${k}=${json[k]}&`
  32. }
  33. str = str.substring(0,str.length-1)
  34. return str
  35. }
  36. export default http

这里要注意这一步不能少

.json的作用是将promise对象解析为一个接送对象,官方的说法是fetch返回的是一个完整的http请求的相应格式,并不能直接被我们使用,这里就需要他们设定的json()方法进行解析,由于基于promise,我们直接将其封装在返回值内,这样就可以直接得到后端原本发给我们的数据了。

return fetch(newUrl,init).then((res)=>{res.json()})

封装后发送

  1. let packageGet = ()=>{
  2. http({
  3. url:'x',
  4. method:'get',
  5. data:{name:"sss",age:18},
  6. }).then((res)=>{
  7. console.log(res)
  8. })
  9. }
  10. let packagePost = ()=>{
  11. http({
  12. url:'x',
  13. method:'post',
  14. data:{"name":"xxx","age":"18"},
  15. }).then((res)=>{
  16. console.log(res)
  17. })
  18. }

一个fetch

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/148398
推荐阅读
相关标签
  

闽ICP备14008679号