发起网络请求的方式

AJAX 全称为Asynchronous Javascript And XML,就是异步的 JS 和 XML。 最大的优势:无刷新发送请求和获取数据。存在于浏览器中Ajax引擎。

xhr:jq/axios对xhr封装

fetch:挂载到window上,兼容性差。

1 xhr

function axios({url, params={}, data={}, method='GET'}) {
      // 返回一个promise对象
      return new Promise((resolve, reject) => {
        // 创建一个XHR对象
        const request = new XMLHttpRequest()
        
        // 根据params拼接query参数:id=1&name=xxx转为json
        let queryStr = Object.keys(params).reduce((pre, key) => {
          pre += `&${key}=${params[key]}`
          return pre
        }, '')
        if (queryStr.length>0) {
          queryStr = queryStr.substring(1)
          url += '?' + queryStr
        }
        // 请求方式转换为大写
        method = method.toUpperCase()
        
        // 初始化一个异步请求(还没发请求)
        request.open(method, url, true)
        // 绑定请求状态改变的监听
        request.onreadystatechange = function () {
          // 如果状态值不为4, 直接结束(请求还没有结束)
          if (request.readyState !== 4) {
            return
          }
          // 如果响应码在200~~299之间, 说明请求都是成功的
          if (request.status>=200 && request.status<300) {
            // 准备响应数据对象
            const responseData = {
              data: request.response,
              status: request.status,
              statusText: request.statusText
            }
            // 指定promise成功及结果值
            resolve(responseData)
          } else { // 请求失败了
            // 指定promise失败及结果值
            const error = new Error('request error staus '+ request.status)
            reject(error)
          }
        }

        // 指定响应数据格式为json ==> 内部就是自动解析好
        request.responseType = 'json'

        // 如果是post/put请求
        if (method==='POST' || method==='PUT') {
          // 设置请求头: 使请求体参数以json形式传递
          request.setRequestHeader('Content-Type', 'application/json;charset=utf-8')
          // 包含所有请求参数的对象转换为json格式
          const dataJson = JSON.stringify(data)
          // 发送请求, 指定请求体数据
          request.send(dataJson)
        } else {// GET/DELETE请求
          // 发送请求
          request.send(null)
        }
      })
    }

2 jquery

     $(function () {
        // 1. 测试GET接口
        $('#btnGET').on('click', function () {
          $.ajax({
            type: 'GET',
            url: 'http://127.0.0.1/api/get',
            data: { name: 'zs', age: 20 },
            success: function (res) {
              console.log(res)
            },
          })
        })
        // 2. 测试POST接口
        $('#btnPOST').on('click', function () {
          $.ajax({
            type: 'POST',
            url: 'http://127.0.0.1/api/post',
            data: { bookname: '水浒传', author: '施耐庵' },
            success: function (res) {
              console.log(res)
            },
          })
        })

        // 3. 为删除按钮绑定点击事件处理函数
        $('#btnDelete').on('click', function () {
          $.ajax({
            type: 'DELETE',
            url: 'http://127.0.0.1/api/delete',
            success: function (res) {
              console.log(res)
            },
          })
        })

        // 4. 为 JSONP 按钮绑定点击事件处理函数
        $('#btnJSONP').on('click', function () {
          $.ajax({
            type: 'GET',
            url: 'http://127.0.0.1/api/jsonp',
            dataType: 'jsonp',
            success: function (res) {
              console.log(res)
            },
          })
        })
      })

3 axios

3.1 发送请求

baseURL配置公共路径,create()根据指定配置创建一个新的axios,应用到不同要求的接口请求中。

import axios from 'axios'

axios.get(`/api1/search/users2?q=${keyWord}`).then(
    response => {成功回调},
    error => {失败回调}
)

//async await简化
async function getUser() {
  try {
    const response = await axios.get('/user?ID=12345');
    console.log(response);
  } catch (error) {
    console.error(error);
  }
}

//get参数
axios.get('/user', {
    params: {
      ID: 12345
    }
})

//post参数
axios.post('/user', {
    firstName: 'Fred',
    lastName: 'Flintstone'
})

      // 指定默认配置
      axios.defaults.baseURL = 'http://localhost:3000'
      // 根据指定配置创建一个新的axios,新axios只是没有取消请求和批量发请求的方法
      const instance = axios.create({
        baseURL: 'http://localhost:4000'
      })

      // 使用instance发请求
      instance.get('/xxx')

      /* 1. GET请求: 从服务器端获取数据*/
      function testGet() {
        // axios.get('/posts?id=1')
        axios({
          url: '/posts',
          params: {
            id: 1
          }
        })
          .then(response => {
            console.log('/posts get', response.data)
          })
      }
  
      /* 2. POST请求: 向服务器端添加新数据*/
      function testPost() {
        // axios.post('/posts', {"title": "json-server3", "author": "typicode3"})
        axios({
          url: '/posts',
          method: 'post',
          data: {"title": "json-server4", "author": "typicode4"}
        })
          .then(response => {
            console.log('/posts post', response.data)
          })
      }
  
      /* 3. PUT请求: 更新服务器端已经数据 */
      function testPut() {
        // axios.put('http://localhost:3000/posts/4', {"title": "json-server...", "author": "typicode..."})
        axios({
          url: '/posts/4',
          method: 'put',
          data: {"title": "json-server5", "author": "typicode5"}
        })
          .then(response => {
            console.log('/posts put', response.data)
          })
      }
  
      /* 4. DELETE请求: 删除服务器端数据 */
      function testDelete() {
        // axios.delete('http://localhost:3000/posts/4')
        axios({
          url: '/posts/5',
          method: 'delete'
        })
          .then(response => {
            console.log('/posts delete', response.data)
          })
      }
  
  
 

3.2 拦截器 

 2d71fa5a8eaeaf4f593a7e99fe7d134d.png

axios.interceptors.request.use(
    config => {
        config.headers.Authorization = token;
        showFullScreenLoading();
        return config;//是为了串联操作,向后传递
    },
    error => {
        return Promise.reject(error);//是为了串联操作,向后传递
    }
);
axios.interceptors.response.use(
    response=> {
        tryHideFullScreenLoading();
        return response;
    }
    error => {
        return Promise.reject(error);
    }
);

f7f1dca2104e6c9ada32b26f5bd17dd3.png

3.3 取消请求

执行cancel函数,传入错误信息message

内部会让cancelPromise变为成功,且成功的值为一个Cancel对象

在cancelPromise的成功回调中中断请求,并让发请求的promise失败,失败的reason为Cancel对象。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>取消请求</title>
</head>
<body>
  <button onclick="getProducts1()">获取商品列表1</button><br>
  <button onclick="getProducts2()">获取商品列表2</button><br>
  <button onclick="cancelReq()">取消请求</button><br>

  <script src="https://cdn.bootcss.com/axios/0.19.0/axios.js"></script>
  <script>

    // 添加请求拦截器
    axios.interceptors.request.use((config) => {
      // 在准备发请求前, 取消未完成的请求
      if (typeof cancel==='function') {
          cancel('取消请求')
      }
      // 添加一个cancelToken的配置
      config.cancelToken = new axios.CancelToken((c) => { // c是用于取消当前请求的函数
        // 保存取消函数, 用于之后可能需要取消当前请求
        cancel = c
      })

      return config
    })

    // 添加响应拦截器
    axios.interceptors.response.use(
      response => {
        cancel = null
        return response
      },
      error => {
        if (axios.isCancel(error)) {// 取消请求的错误
          // cancel = null
          console.log('请求取消的错误', error.message) // 做相应处理
          // 中断promise链接
          return new Promise(() => {})
        } else { // 请求出错了
          cancel = null
          // 将错误向下传递
          // throw error
          return Promise.reject(error)
        }
      }
    )


    let cancel  // 用于保存取消请求的函数
    function getProducts1() {
      axios({
        url: 'http://localhost:4000/products1',
      }).then(
        response => {
          console.log('请求1成功了', response.data)
        },
        error => {// 只用处理请求失败的情况, 取消请求的错误的不用
          console.log('请求1失败了', error.message)          
        }
      )
    }

    function getProducts2() {

      axios({
        url: 'http://localhost:4000/products2',
      }).then(
        response => {
          console.log('请求2成功了', response.data)
        },
        error => {
          console.log('请求2失败了', error.message)
        }
      )
    }

    function cancelReq() {
      // 执行取消请求的函数
      if (typeof cancel === 'function') {
        cancel('强制取消请求')
      } else {
        console.log('没有可取消的请求')//pending状态才需要取消,取消后会进入失败的回调
      }
    }
  </script>
</body>
</html>

4 fetch

        fetch(`/api1/search/users2?q=${keyWord}`).then(
			response => {
				console.log('联系服务器成功了');
				return response.json()//返回promise实例
			},
		).then(
			response => {console.log('获取数据成功了',response);},
		).catch(
			error => {
				console.log('请求出错',error);
			}
        )

        //优化版
		try {
			const response= await fetch(`/api1/search/users2?q=${keyWord}`)
			const data = await response.json()
			console.log(data);
		} catch (error) {
			console.log('请求出错',error);
		}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值