前端AJAX基础

AJAX学习

Ajax的概念:

Ajax用来实现客户端网页请求服务器的数据,当用户有操作时可以实时更新部分模块或者整个网页


先引入axios库 官网:http://www.axios-js.com/

axios基本语法:

模板:
   axios({
         method: '',
         url: '',
        }).then((result) => {
   //.then 用来指定请求成功之后的回调函数
  // 形参中的result是请求成功之后的结果
        })

then方法(或回调函数)负责接受发过来的数据

属性区分大小写

axios GET 请求:
  axios({
    method: '请求的类型',
    url: '请求的URL地址',
     params: {id: 1, bookname: '红楼梦'} 
     // params用于传递参数,可选
  }).then((result) => {})

Demo:为button绑定一个click事件并发送get请求,注意params可省

    $('button').on('click', function() {
        axios({
            method: 'GET',
            url: 'http://www.liulongbin.top:3006/api/getbooks',
            params: {
                id: 3
            },
        }).then(result => {      //then控制请求成功
            console.log(result.data.data);   
        }).catch(err => {        //catch控制请求失败(扩展)

get参数的本质就是把所有属性用=链接、&符号分隔、放到路径的最末尾(前面要加?)

Demo:

http://www.liulongbin.top:3006/getbook?id=1&bookname=红楼梦

注意不能有空格和中文等特殊字符,浏览器会对URL的中文进行编码处理

编码和解码

在这里插入图片描述

axios的解构赋值
        axios({
        method: 'GET',
        url: 'http://www.liulongbin.top:3009/api/getbooks'
        }).then(({data: res}) => {
        // 从 .then(fn) 回调函数的形参中,解构赋值出 data 属性,重命名为 res
        console.log(res)
        })

因为ajax拿的参数中最重要的就是data,在then回调函数中通过对象解构把data的参数赋值到一个res的变量中(名称随意),然后对这个json进行操作

then返回的数据:
在这里插入图片描述

axios POST 请求:

POST请求一定得有参数,因为POST就是推数据给服务器

        axios({
            method: 'POST',
            url: 'http://www.liulongbin.top:3009/api/addbook',
            data: {             //post用的是data传递请求参数
                bookname: '三体',
                author: '刘慈欣',
                publisher: '北京人民出版社'
            },
        }).then(({data: res}) => {
            console.log(res);
        })

请求报文和响应报文
  • 客户端发请求给服务器,请求报文规定数据格式

  • 服务器回数据,响应报文规定数据格式
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    注意的是响应码和状态码不同,下面展示的是响应码
    在这里插入图片描述

  • 响应码由http协议制定,一般都约定俗成

  • 状态码不唯一,在接收到的数据中,可以由后端人员自己定义;就好比客户端无法请求数据大部分都返回404

响应状态码表示与服务器端的通信请求是否成功,而状态码表示业务处理的状态,一般会由后端给你写在接口文档里,供需要时查阅

Ajax表单数据提交

一般的表单分为三个模块:表单标签form、表单域(inputtextareaselect),表单按钮(submitreset

  • 表单的作用就是收集数据
阻止默认行为:
$('form').on('submit', function (e) {
  e.preventDefault();
})

为什么需要阻止默认行为?
默认的表单元素如果没有action参数,也就是没有设置url的话默认会刷新页面,设置了就会跳转,如果只是收集数据,我们应该阻止浏览器默认行为

Jquery 中的 serialize 方法:

$('form').serialize()方法会拿表单中所有的带name属性的数据,以a=1&b=2(只是举例)这样的字符串数据类型发送请求

利用 serialize 请求数据:

        $('form').on('submit', function(e) {
            e.preventDefault();
            axios.post('http://www.liulongbin.top:3009/api/form', $('form').serialize()
            ).then(({data: res}) => {
                console.log(res);
            })
        })

细看请求包:
在这里插入图片描述
关注两个点就行:

  • application后面是/x-www-form-urlencoded(一般形式的getpost请求回的包都是json类型)
  • data是以字符串形式传参的
使用 别名传参:
	axios.get('http://www.liulongbin.top:3009/api/get').then(res => {
           console.log(res.data);
     })
    axios.post('http://www.liulongbin.top:3009/api/post', {name: '123',}).then(res => {
           console.log(res.data);
      })
  • 注意的是用post必须得有参数,而且第二个(data)参数可以是{}对象这种,也可以是json或者FormData等变量

其他别名(就是懒人语法/语法糖):

axios.delete(url,[]);
axios.put(url,[data{}])
axios.patch(url,[]);
全局配置根路径:

也是语法糖,但是有优点,项目里可以经常用,易于维护而不需要大量修改

方法①

语法

    axios.interceptors.request.use(function(config) {
      config.url = '根路径url' + config.url
      return config;
    }) 

方法②

拦截器

    axios.interceptors.request.use(function(config) {
      config.url = '根路径url' + config.url
      return config;
    }) 

axios拦截器:

在这里插入图片描述
在代码中: 拦截器配置在axios文件的下面script语句的前面
语法格式:

axios.interceptors.request / response.use(function (config) {
    // 在发送请求之前做些什么
    return config;
}, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
});

  • 注意use中放两个函数就行,一个成功干什么,一个错误干什么
FormData:

FormData是浏览器的一个Web Api它是一个原生DOM! FormData配合ajax,能够向浏览器发送multipart/form-data编码格式的数据,一般用于文件上传

FormData是一个构造函数,使用new可以拿到FormData对象

const fd = new FormData()

利用表单点击事件拿到FormData对象(注意的是用的原生DOM

let form = document.querySelector('form');
        form.addEventListener('submit', function(e) {
            e.preventDefault();
            let fd1 = new FormData(form);
            console.log(...fd1);
        })

调用FormData对象的append(键,值)方法

fd.append(‘username’, ‘Lion’)

注意键名必须是字符串

使用FormData请求一次数据:

    const fd = new FormData;
    fd.append('name', 'Lion');
    fd.append('value', 'is man'
          axios.post('http://www.liulongbin.top:3009/api/formdata', fd).then(({data: res}) => {
            console.log(res);
        })

细看请求包,确认传参成功:

在这里插入图片描述


数据交换原理

JSON数据类型:

全称:JavaScriptObjectNotation

可以理解为一个键值对都是字符串的数据格式,在C++python等多种语言中都有这种数据类型

服务器和客户端常用的两种数据交换格式为:XML和JSON;早期则是XML、目前主流格式为JSON
JSON数据的格式:

可以是: 对象、数组、布尔值、null
不可以是: undefinedfunction

JSON语法要求`:
  1. 属性名必须使用双引号
  2. 不允许单引号表示字符串
  3. 不能写注释
  4. 最外层必须是对象或者数组
JSON 中 Ajax 常用方法:

反序列化: JSON格式转JS数据

JSON.parse()

序列化:JS数据转JSON格式;为前一个方法的逆运算

JSON.stringgify()

在这里插入图片描述

Ajax底层 ==> XMLHttpRequest

  • 什么是XMLHttpRequest

是浏览器内置的一个构造函数(也就意味着它是原生的);也是ajax的核心对象
axios中的getpost,包括axios本身都是基于它(简称XHR)封装出来的

不用axios,自己用XHR也是可以给服务器发包的
分为四步:

  1. 实例化xhr
  2. 调用xhr.open()指定请求方法
  3. 调动xhr.send()发送数据
  4. 监听load事件并用xhr.response()方法接受响应报文

使用xhr发送GET

        document.querySelector('button').onclick = function() {
            const xhr = new XMLHttpRequest();
            xhr.open('GET','http://www.liulongbin.top:3009/api/get');
            xhr.send();
            xhr.addEventListener('load', function() {
                console.log(JSON.parse(xhr.response)); 
                //接受过来的数据是纯字符串,转换成JSON更清晰
            })
        }

使用xhr发送POSt

        document.querySelector('button').onclick = function() {
            const xhr = new XMLHttpRequest();
            xhr.open('POST','http://www.liulongbin.top:3009/api/post');
            xhr.send('name: David');
            xhr.addEventListener('load', function() {
                console.log(JSON.parse(xhr.response));
            })
        }

注意:send默认只发送字符串格式的参数,除非传参FormData变量或者setRequestHeader手动指定报头

也可以使用类似HTML表单标签的方式设置请求类型发送POST

JSON:
  document.querySelector('button').onclick = function() {
            const xhr = new XMLHttpRequest();
            xhr.open('POST','http://www.liulongbin.top:3009/api/post');
            xhr.setRequestHeader('content-type', 'application/json'); 
            //大小写无所谓,浏览器会做处理
            xhr.send(`{"name": "David", "age": "18"}`); 
            //JSON必须键值对都用双引号
            xhr.addEventListener('load', function() {
                console.log(JSON.parse(xhr.response));
            })
        }

Request Headers:
在这里插入图片描述

字符串(a=1&b=2这种):
  document.querySelector('button').onclick = function() {
            const xhr = new XMLHttpRequest();
            xhr.open('POST','http://www.liulongbin.top:3009/api/post');
            xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded'); 
            //大小写无所谓,浏览器会做处理
            xhr.send('name=David&age=18');  
            //字符串参数
            xhr.addEventListener('load', function() {
                console.log(JSON.parse(xhr.response));
            })
        }

Request Headers:
在这里插入图片描述
在这里插入图片描述

注意:如果漏写&z或者其他符号就会被浏览器认为是单个属性(键名),而就不是收到如上图所示的键值对形式了
FormData:
 document.querySelector('button').onclick = function() {
            const fd = new FormData();
            fd.append('name', 'David');
            fd.append('age', '18');
            const xhr = new XMLHttpRequest();
            xhr.open('POST', 'http://www.liulongbin.top:3009/api/post');
            xhr.send(fd);
            //无需设置setRequestHeader, 默认转换
            xhr.addEventListener('load', function() {
                console.log(JSON.parse(xhr.response));
            })

Request Headers:
在这里插入图片描述

注意:load事件是异步任务,位置可以随意放置

Jquery 中的 Ajax:

Jquery中对于ajax封装了三个方法:

$.get() | $.post() | $.ajax()
  • axios有一些不同
  • (因为axios是基于Jquery的ajax方法改进而成的)
$.get():
            $.get('http://www.liulongbin.top:3009/api/getbooks',{id:2}, 
            function(res) {
                console.log(res);
            })

$.post()
            $.post('http://www.liulongbin.top:3009/api/addbook',{
                bookname: 'djy', author: 'dsy', publisher: '谁知道'
            }, function(res) {
                console.log(res);
            })

$.ajax()
           $.ajax({
                method:'post',
                url: 'http://www.liulongbin.top:3009/api/addbook',
                data: {
                  	bookname: 'dsypig',
                    author: 'dsypig',
                    publisher: '谁知道'
                },
                success: function(res) {
                    console.log(res);
            }})

区分:

  1. thensuccess替代
  2. success的形参不需要结构,直接返回值的data部分
  3. 请求参数不似axios不分区getparamspostdata
  4. jquery中的拦截器必须自己手动设置,跟axios的不为同一个!
利用$ajax.()实现上传文件(或者发送FormData对象)

jQuery中的ajax比较特殊,上传文件(或者说发送FormData对象)必须带两个参数:

contentType: false  //取消默认设置文件头信息
processData: false  //取消对文件默认的编码
利用$ajax.()实现CORS跨域
$ajax({
	dataType: 'jsonp'
	//json | text | html | xml | script 
})

dataType:改变底层的请求方式和请求报头,不再让它使用XHR、而是使用script标签发包(script标签不与同源策略冲突)并且返回值是jsonp格式(也可以指定其他返回格式)

返回值格式:

在这里插入图片描述

同源策略:

  • 什么是同源?

同源值得是两个URL地址具有相同的协议、主机名、端口号

如果不同源直接发包,则是跨域请求

http的默认端口是80、https是443 默认不写浏览器也能识别
  • 为什么会有跨域?

浏览器的安全策略:
它不允许非同源的URL进行资源交互
跨域的请求会被放行,但是响应包会被拦截

跨域的解决方案:

方案诞生的时间方案来源优点缺点
JSONP出现较早民间兼容性好仅支持get请求
CORS出现较晚W3C支持五种常见请求方式兼容性
CORS是跨域的主流技术解决方案,但是面试官喜欢JSONP
深入:

CORS用到了XMLHTTPRequest对象,是纯正的ajax请求
JSONP没有用XMLHTTPRequest对象,是偏方

只要涉及和用到了XMLHTTPRequest,就是ajax请求

底层:

CORS(后端方案、我暂时不研究):

JSONP(需要后端配合的方案):
JSONP在底层是用到了script标签的src属性,script标签的src属性不受同源策略限制,与之类似的还有a标签的跳转、imgsrc,它是把非同源的src请求到本地然后执行

<script src="http://www.liulongbin.top:3009/api/jsonp?callback=showInfo&name=david">
</script>
<script>
    function showInfo(res) {console.log(res);}
</script>

因为script标签只能发送get请求,而且在工作中前端和后端要约定一致一个函数名,对不上会出问题,还可以在标签里写callback回调函数的形式告诉后端要返回什么样的函数名、以及传少量的字符串参数

防抖和节流

防抖是指频繁触发某个操作只执行最后一次
在这里插入图片描述
实现:

  1. 定义一个延时器
  2. 事件开始之前清除延时器
  3. 触发事件后延迟一段时间,如果没有继续被触发,则执行回调函数;如果又被触发,重新计时

节流是指单位时间内某个操作只执行触发一次
在这里插入图片描述
实现:

执行函数时,if判断某种状态或者计时,如果未满足条件或者计时器没有结束则return;如果条件为真或者到单位时间设置flagtrue;继续执行下面的函数


版权声明:本文为qq_45149045原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。