Ajax和axios的基础知识

116 阅读6分钟

前言

该文章记录的是一些关于Ajax和axios的基础知识,后续将会慢慢添加完善相关的所有知识,所有内容均从网上整理而来,加上自己的一些理解,方便在工作中使用。

一、Ajax

1. Ajax 简介

AJAX 全称为Asynchronous JavaScript And XML,就是异步的JS 和XML;通过AJAX 可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据

2. Ajax 优缺点

  • 优点
    • 可以无需刷新页面而与服务器端进行通信
    • 根据用户操作事件来更新部分页面内容
  • 缺点
    • 没有浏览记录,不能回退
    • 存在跨域问题
    • SEO不友好

3. HTTP相关问题

  • MDN相关文档

developer.mozilla.org/zh-CN/docs/…

  • HTTP 请求交互的基本过程

20210302161144256.png

  1. 从浏览器端向服务器发送HTTP 请求(请求报文)
  2. 后台服务器接收到请求后, 处理请求后, 向浏览器端返回HTTP响应(响应报文)
  3. 浏览器端接收到响应, 解析显示响应体/调用监视回调

4. Ajax基本使用

  • 基本语法
    //1.创建XMLHttpRequest 对象
    let xhr = new XMLHttpRequest()
    
    //2.设置请求信息(请求方法和url)
    // 请求方式 method常用'GET'和'POST'
    xhr.open(method, url)
    //可以设置请求头,一般不设置, 第一个参数是名,第二个参数是内容
    //xhr.setRequestHeader('xxx', 'xxxx')
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
    
    //3.发送请求
    xhr.send([参数]) //get请求不传参数,只有post请求使用,[]表示选填
    
    //4.接收响应
    //xhr.responseXML 接收 xml格式 的响应数据
    //xhr.responseText 接收 文本格式 的响应数据
    xhr.onreadystatechange = function (){
    // readyState 是 xhr对象中的属性, 表示状态 0 1 2 3 4
     if(xhr.readyState == 4 && ){ //4表示完成状态
       //一般成功状态在200~300之间
       if(xhr.status >= 200 && xhr.status < 300){
           console.log(xhr.responseText)
       }	
     }
    }
    

二、axios

1. axios简介

Axios 是一个基于 promise 网络请求库,作用于node.js 和浏览器中。中文网

2. axios引入

  • 使用 npm

npm install axios

  • 使用 CDN

<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

3. axios基本使用

3-1. axios 请求配置config

这些是创建请求时可以用的配置选项。只有 url 是必需的。如果没有指定 method,请求将默认使用 GET 方法。

{
    // `url` 是用于请求的服务器 URL 
    url: '/user',
    
    // `method` 是创建请求时使用的方法 
    method: 'get', // 默认值
    
    // `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。
    baseURL: 'https://some-domain.com/api/',
    
    // 自定义请求头,键值对形式
    headers: {'X-Requested-With': 'XMLHttpRequest'},
    
    // `params` 是与请求一起发送的 URL 参数
    // 必须是一个简单对象或 URLSearchParams 对象 
    params: { 
        ID: 12345 
    },
    
    // `data` 是作为请求体被发送的数据
    // 仅适用 'PUT', 'POST', 'DELETE 和 'PATCH' 请求方法
    // 在没有设置 `transformRequest` 时,则必须是以下类型之一
    // string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
    // 浏览器专属: FormData, File, Blob 
    // Node 专属: Stream, Buffer
    data: { 
        firstName: 'Fred' 
    },
    
    // `timeout` 指定请求超时的毫秒数。
    // 如果请求时间超过 `timeout` 的值,则请求会被中断
    timeout: 1000, // 默认值是 `0` (永不超时)
    
    //`responseType` 表示浏览器将要响应的数据类型
    // 选项包括: arraybuffer, document, json, text, stream
    //  浏览器专属:'blob' 
    responseType: 'json', // 默认值
    
    // ···· 还有很多参数
}

3-2. axios 默认配置

可以指定默认配置,它将作用于每个请求,不用再每个单独重复设置

//设置baseURL
axios.defaults.baseURL = 'https://api.example.com';

//设置每次请求的请求头
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN; 
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

注意:默认配置的优先级没有单独设置高,即实例的defaults属性的优先级没有config参数的优先级高

3-3. axios 常用API

注意:config是axios的请求配置,详情注意看官网文档

  • axios(config)
    // 发一个get请求
    axios({
      method: 'GET',
      url: "http://localhost:3000/posts",
      params: {
        id: 3
      }
    }).then(res => {
      console.log(res)
    })
    
    // 发起一个post请求 
    axios({ 
        method: 'post', //请求方式
        url: '/user/12345',  //请求路径
        data: { 
            firstName: 'Fred', 
            lastName: 'Flintstone' 
        }
    });
    
  • axios.get(url, [config])
    axios.get('http://localhost:3000/posts', { 
        timeout: 10000, 
        params: { id: 3 } 
    }).then(res => {
     console.log(res)
    })
    
  • axios.post(url, [data] ,[config])
    axios.post('http://localhost:3000/posts', {
      title: '虎年',
      author: '李白'
    }, {
      timeout: 10000
    }).then(res => {
      console.log(res)
    })
    
  • axios.create([config]) --自定义配置新建一个实例

axios.create自定义配置新建一个实例,作用在于config里面配置可以不一样;axios.create()返回的实例与axios使用方法基本一致

//接口的地址不同,可以使用axios.create生成实例
let oldAxios= axios.create({
    baseURL:'http://localhost:3000'
})

let newAxios= axios.create({
    baseURL:'http://localhost:6000'
})

//通过实例 
oldAxios.post('/posts', {
    title: '虎年',
    author: '李白'
}, {
    timeout: 10000
}).then(res => {
    console.log(res)
})

//和上面实例调用结果一模一样
axios.post('http://localhost:3000/posts', {
    title: '虎年',
    author: '李白'
}, {
    timeout: 10000
}).then(res => {
    console.log(res)
})

3-4. axios 响应结构

{ 
    //  `data` 由服务器提供的响应 
    data: {}, 
    
    // `status` 来自服务器响应的 HTTP 状态码 
    status: 200, 
    
    // `statusText` 来自服务器响应的 HTTP 状态信息 
    statusText: 'OK', 
    
    // `headers` 是服务器响应头 
    // 所有的 header 名称都是小写,而且可以使用方括号语法访问 
    // 例如: `response.headers['content-type']` 
    headers: {}, 
    
    // `config``axios` 请求的配置信息 
    config: {}, 
    
    // `request` 是生成此响应的请求 
    // 在node.js中它是最后一个ClientRequest实例 (in redirects), 
    // 在浏览器中则是 XMLHttpRequest 实例 
    request: {} 
}

当使用 then 时,您将接收如下响应:

axios.get('/user/12345') 
.then(function (response) { 
    console.log(response.data); 
    console.log(response.status); 
    console.log(response.statusText); 
    console.log(response.headers); 
    console.log(response.config); 
});

3-5. axios 拦截器

在请求或响应被 then 或 catch 处理前拦截它们。

  • 请求拦截器:每次发请求前拦截,可以修改请求的一些参数
  • 响应拦截器:每次响应回来时拦截,可以修改一些返回的数据
// 添加请求拦截器 
axios.interceptors.request.use(function (config) { 
    // 在发送请求之前做些什么
    return config; 
    }, function (error) {
    // 对请求错误做些什么 
    return Promise.reject(error); 
});


// 添加响应拦截器 
axios.interceptors.response.use(function (response) {
    // 2xx 范围内的状态码都会触发该函数。 
    // 对响应数据做点什么 
    return response; 
    }, function (error) { 
    // 超出 2xx 范围的状态码都会触发该函数。
    // 对响应错误做点什么
    return Promise.reject(error); 
});

三、vue中封装的axios

// 引入qs
import Qs from 'qs';
import axios from "axios";
import {dns} from "@/utils/dns.js"

// 请求默认地址
axios.defaults.baseURL = dns;
// 设置请求超时
axios.defaults.timeout = 10000;

// 设置请求拦截器(在请求发送出去之前 带上一些东西)
axios.interceptors.request.use(config => {
  // 每次发送请求前判断token,存在就在header加上token,如果过期所以在响应拦截器中要对返回状态进行判断
  // const token = localStorage.token
  // token && (config.headers.Authorization = token)
  return config;
}, err => Promise.reject(err))

// 设置响应拦截器 在接收到后端的响应结果以后 统一处理
axios.interceptors.response.use(
  response => {
    // 如果返回的状态码为200,说明接口请求成功
    if (response.status === 200) {
      return Promise.resolve(response)
    } else {
      return Promise.reject(response)
    }
  }, 
  error => {
    if (error.response.status) {
      // 根据不同状态码提示不同错误
      // switch (error.response.status) {
      //   case 401:
      //     break
      //   case 403:
      //     break
      //   default:
      //     break
      // }
      return Promise.reject(error)
    }
  }
)

// 封装get方法
export function get (url, params) {
  return new Promise((resolve, reject) => {
    axios.get(url, {
      params: params
    }).then(res => {
      resolve(res.data)
    }).catch(err => {
      reject(err.data)
    })
  })
}

/**
 * post方法,对应post请求
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
 */
export function post (url, params) {
  return new Promise((resolve, reject) => {
    axios.post(url, Qs.stringify(params))
      .then(res => {
        resolve(res)
      })
      .catch(err => {
        reject(err)
      })
  })
}