一篇文章搞定Ajax

199 阅读6分钟

Ajax总结

Ajax简介

Ajax 是浏览器中的技术:用来实现客户端网页请求服务器的数据。
它的英文全称是 Asynchronous Javascript And XML,简称 Ajax。

Ajax请求数据的五种方式

序号请求方式描述
1post向服务器新增数据
2get从服务器获取数据
3delete删除服务器上的数据
4put更新服务器上的数据(侧重于完整更新:例如更新用户的完整信息)
5patch更新服务器上的数据(侧重于部分更新:例如只更新用户的手机号)

axios库:

axios(发音:艾克C奥斯) 是前端圈最火的、专注于数据请求的库

基本语法:

axios({
	method:'请求的类型',
	url:'请求的url地址'
}).then(res=>{
	//要执行的操作
 	})

form 表单

form标签的属性一览表

属性可选值说明
action接口的url地址把表单采集到的数据,提交到哪个接口中
methodget或post数据的提交方式(默认值为 GET)

注意点:每个表单域必须包含 name 属性,否则用户填写的信息无法被采集到!

axios请求方法的别名

get方法

// 不带查询参数
axios.get('http://www.itcbc.com:3006/api/get').then(result => {
    console.log(result);
})
// 带查询参数
axios.get('http://www.itcbc.com:3006/api/get', {
    params: { id: 1 }
}).then(result => {
    console.log(result);
})

post方法

// 不带请求体
axios.post('http://www.itcbc.com:3006/api/post').then(result => {
    console.log(result);
})
// 带请求体
axios.post('http://www.itcbc.com:3006/api/post', {
    username: 'zhangsan',
    password: '123456'
}).then(result => {
    console.log(result);
})

axios 全局配置 & 拦截器

全局配置请求根路径 - 语法格式

// 全局配置根路径
axios.defaults.baseURL = 'http://www.itcbc.com:3006';
// 请求接口时,不用写根路径
axios.get('/api/get').then(result => {
    console.log(result);
})
// 请求接口时,不用写根路径
axios.post('/api/post', { username: 'zhangsan', password: '123456'}).then(result => {
    console.log(result);
})

拦截器

拦截器(interceptors)用来全局拦截 axios 的每一次请求与响应。

好处:可以把每个请求中,某些重复性的业务代码封装到拦截器中,提高代码的复用性

// request:请求:所有请求都会经过这个拦截器
axios.interceptors.request.use(
  function(config) {
    // 在发送请求之前做些什么
    document.querySelector('.loading').style.display = 'block'
    return config
  },
  function(error) {
    // 对请求错误做些什么
    return Promise.reject(error)
  }
)

// 添加响应拦截器
// response:响应,所以响应都会经过这个拦截器
axios.interceptors.response.use(
  // 响应成功所经过的处理函数
  function(response) {
    // 对响应数据做点什么
    document.querySelector('.loading').style.display = 'none'
    return response
  },
  // 响应失败所经过的处理函数
  function(error) {
    // 对响应错误做点什么
    document.querySelector('.loading').style.display = 'none'
    return Promise.reject(error)
  }
)

FormData

基本用法

// 1. 获取 form 标签的 DOM对象
let form = document.querySelector('form');
// 2. 实例化 FormData 对象,传入 form
let fd = new FormData(form);
// 3. 提交数据
axios.post('/api/formdata', fd).then(result => {
    console.log(result);
})
注意点:每个表单元素都具有 name 属性

FormData的API方法

append('key', 'value'); -- 向对象中追加数据
set('key', 'value');    -- 修改对象中的数据
delete ('key');         -- 从对象中删除数据
get('key')              -- 获取指定key的一项数据
getAll('key')           -- 获取指定key的全部数据
forEach()               -- 遍历对象中的数据

文件对象

获取文件对象

<input type="file" multiple />
<script>
    // 文件域内容改变的时候,获取文件列表及文件对象
    document.querySelector('input').onchange = function () {
        // 文件列表 (用户选择的文件列表)得到一个伪数组,里面存放了一个一个的文件对象
        let fileList = this.files;
        // 判断,是否选择了文件
        if (fileList.length === 0) return;
        // 获取某个文件对象,比如第一个文件的文件对象
        let fileObj = fileList[0];
    }
</script>

作用:

本地预览

// 文件域内容改变的时候,获取文件列表及文件对象
document.querySelector('input').onchange = function () {
    // 文件列表 (用户选择的文件列表)得到一个伪数组,里面存放了一个一个的文件对象
    let fileList = this.files;
    // 判断,是否选择了文件
    if (fileList.length === 0) return;
    // 获取某个文件对象,比如第一个文件的文件对象
    let fileObj = fileList[0];
    // 创建本地文件的预览url
    let url = URL.createObjectURL(fileObj);
    // 设置图片的src为url
    document.querySelector('img').src = url;
}

追加到FormData,实现文件上传

// 文件域内容改变的时候,获取文件列表及文件对象
document.querySelector('input').onchange = function () {
    // 文件列表 (用户选择的文件列表)得到一个伪数组,里面存放了一个一个的文件对象
    let fileList = this.files;
    // 判断,是否选择了文件
    if (fileList.length === 0) return;
    // 获取某个文件对象,比如第一个文件的文件对象
    let fileObj = fileList[0];
    // 追加到FormData对象中
    let fd = new FormData();
    fd.append('avatar', fileObj);
    // axios 提交 fd 到指定的接口,从而实现文件上传
    // axios提交FormData的代码略
}

获取数据的三种形式

key=value(查询字符串格式)

{key:value} (JSON格式)

formdata(FormData对象格式)

请求报文&响应报文

请求报文规定了客户端以什么格式把数据发送给服务器

响应报文规定了服务器以什么格式把数据响应给客户端

请求的时候,设置了不同格式的请求体,需要一个对应的请求头

第一种格式:参数=值&参数=值————>Content-Type: application/x-www-form-urlencoded

第二种格式: '{ "id": 1, "name": "zs" }'————>Content-Type: application/json

第三种格式: new FormData()————>Content-Type: multipart/form-data; xxsd随机字符(不用设置,浏览器自动设置)

XMLHttpRequest

XMLHttpRequest是浏览器内置的一个构造函数

作用:基于 new 出来的 XMLHttpRequest 实例对象,可以发起 Ajax 的请求。

axios中的axios.get(),axios.post(),axios() 方法,都是基于 XMLHttpRequest(简称:XHR)封装出来的!

使用XMLHttpRequest发起请求

主要的 4 个实现步骤:
创建 xhr 对象
调用 xhr.open() 函数
调用 xhr.send() 函数
监听 load 事件

请求时携带URL参数或提交请求体

let xhr = new XMLHttpRequest();
xhr.addEventListener('load', function () {
  console.log(this.response);
})
// 将请求参数拼接到url后面
xhr.open('请求方式', 'http://www.itcbc.com/api/xx?id=1&username=zhangsan');
xhr.send( 请求体 );

提交请求体数据,需指定Content-Type头

let xhr = new XMLHttpRequest();
xhr.addEventListener('load', function () {
  console.log(this.response);
})
// 将请求参数拼接到url后面
xhr.open('POST', 'http://www.itcbc.com/api/post');

// 根据请求体格式的不同,需设置对应的Content-Type头
xhr.setRequestHeader('Content-Type', '值')
xhr.send('username=zs&age=20');

JSON的语法要求

属性名必须使用双引号包裹
字符串类型的值必须使用双引号包裹
JSON 中不允许使用单引号表示字符串
JSON 中不能写注释
JSON 的最外层必须是对象或数组格式(其他类型也可以,但多数是对象或数组格式)
不能使用 undefined 或函数作为 JSON 的值

数据交换

调用浏览器内置的 JSON.parse() 函数,可以把 JSON 格式的字符串转换为 JS 数据
调用浏览器内置的 JSON.stringify() 函数,可以把 JS 数据转换为 JSON 格式的字符串

封装自己的Ajax函数

// {name:'jack',age:20} >> name=jack&age=20
function parseObjectToString(obj) {
  let arr = []
  for (let key in obj) {
    arr.push(key + '=' + obj[key])
  }
  return arr.join('&')
}

// option.method:请求方式
// option.url:请求地址
// option.params:url参数
// option.data:请求体参数
// success:请求成功之后的回调函数
function ajax({ method, url, params, data, success }) {
  // 1.创建异步对象
  let xhr = new XMLHttpRequest()
  // 2.使用异步对象发起请求
  // 2.1 设置请求行
  if (method.toLowerCase() == 'get' && params) {
    url += '?' + parseObjectToString(params)
  }
  xhr.open(method, url)
  // 2.2 设置请求头
  // 2.3 设置请求体
  // instanceof:判断一个的构造函数是否是某个构造函数,意味着判断对象是否是某个构造函数创建的
  if (data instanceof FormData) {
    // 说明传递了formdata ,不用设置请求头
    xhr.send(data)
  } else if (typeof data == 'object') {
    // 说明传递了一个对象
    xhr.setRequestHeader('Content-Type', 'application/json')
    xhr.send(JSON.stringify(data))
  } else if (typeof data == 'string') {
    // 说明这里传递key=value&key=value
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
    xhr.send(data)
  } else {
    xhr.send()
  }

  // 3.使用异步对象接收响应
  xhr.addEventListener('load', function() {
    // 调用用户传入的回调函数,且将后台的响应数据做为参数回传
    success(JSON.parse(xhr.response))
  })
}