Ajax基础

240 阅读3分钟

服务器相关的基础概念

服务器的作用

  • 存储一个网站的文件(HTML、CSS、JS、图片、音乐.....)
  • 提供网站的文件给用户。
  • 在前端开发中,客户端指的是浏览器
  • 网页中用到的资源存储在服务器

URL 地址

  • URL 地址,表示服务器上每个资源的确切位置。
  • 服务器上的每个资源,都对应着独一无二的URL地址。
  • 数据也是服务器上的资源,对数据的操作也对应着不同的URL地址:
    • 增加:getbooks
    • 添加:addbook
    • 删除:delbook
    • 修改:updatebook
  • 请求响应:
    • 请求是由客户端发送的。
    • 响应是由服务器做出的。

请求方式

使用 Ajax 请求数据的 5 种方式

  • 操作服务器上的数据除了要使用 URL地址,还需要指定请求方式。

1650814985521.png

Ajax基础用法

<script>
    axios ({
        method: '请求的类型',
        url: '请求的URL地址',
    }).then((result) => {

    });
</script>
  • then 用来指定请求成功之后的回调函数。
  • 形参中的result是请求成功之后的结果。

接口相关的基础概念

接口的概念

  • 使用 Ajax 请求数据时,被请求的 URL 地址,就叫做数据接口(简称:接口或 API 接口)。
  • 每个接口必须有对应的请求方式。

接口文档的格式

1650877800723.png

form表单

表单的三个组成部分

网页中采集数据的表单由三个部分组成,分别是:表单标签、表单域、表单按钮。

  • 表单标签:
    • HTML 的 就是表单标签,它是一个“容器”,用来将页面上指定的区域划定为表单区域。
  • 表单域:
    • 表单域提供了采集用户信息的渠道,常见的表单域有:input、textarea、select 等。
  • 表单按钮:
    • 当表单数据填写完毕后,用户点击表单按钮,会触发表单的提交操作,从而把采集到的数据提交给服务器
  • form表单的作用是采集数据
  • 把表单采集到的数据提交给服务器时,需要指定请求的方式请求的 URL 地址

标签的属性

标签最重要的三个属性分别是 action、method 和 enctype 。
  • action

    • 可选值:接口的URL地址。
    • 说明:把表单采集到数据,提交到哪个接口中。
  • method

    • 可选值:GET 或 POST 。
    • 说明:数据的提交方式(默认值为GET)
  • enctype

    • 可选值:application / multipart / form-data

      ​ / x-www-form-urlencoded

    • 说明:数据的编码格式。把表单数据提交给服务器之前,如何对将要提交的数据进行编码(默认值 x-www-form-urlencoded)

    • 只能搭配 POST 提交方式一起使用;如果是 GET 提交,则 enctype 没有意义!

  • 在 标签上,通过 action 属性指定提交的 URL 地址,通过 method 属性指定提交的方式为 GET

  • 在 标签上,通过 action 属性指定提交的 URL 地址,通过 method 属性指定提交的方式为 POST,并通过 enctype 属性指定数据的编码方式为 application/x-www-form-urlencoded

通过 Ajax 提交表单数据

​ 通过 Ajax 提交表单采集到的数据,可以防止表单默认提交行为导致的页面跳转问题,提高用户的体验。

  • jQuery 的 serialize() 函数
    • jQuery 的 serialize() 函数能够一次性获取到表单中采集的数据。
    • 语法:$('表单元素的选择器').serialize();
    • 该方法 能够 获取 隐藏域的值。
    • 在使用 serialize() 函数快速获取表单数据时,必须为每个表单域添加 name 属性

axios 请求方法的别名

简化方法的参数

  • axios.get(Url, {params:{参数} })

    <script>
    axios.get("http://www.itcbc.com:3006/api/getbooks?appkey=wanshao1234")
    .then(result=>{
        console.log(result);
    })
    </script>
    
  • axios.post(url,参数(字符串格式));

    <script>
    const url = 'http://www.itcbc.com:3006/api/addbook';
    const query = 'bookname=2019&author=2020&publisher=2021&appkey=qqq777';
     axios.post(url,query).then((result) => {
            console.log(result);
     });
    </script>
    
  • axios.delete ( url , config )

  • axios.put ( url, data , config )

  • axios.patch ( url, data , config )

axios 全局配置 & 拦截器

全局配置请求根路径

  • 固定配置:axios.defaults.baseURL = '请求根路径'

拦截器

  • 拦截器(interceptors)用来全局拦截 axios 的每一次请求与响应。
  • 可以把每个请求中,某些重复性的业务代码封装到拦截器中,提高代码的复用性。
  • 使用拦截器实现 loading 效果:
    • 在请求拦截器中展示:$('.loading-box').show()

    • 在响应拦截器中隐藏:$('.loading-box').hide()

FormData和文件上传

FormData

  • FormData 是一个浏览器对象。用于管理表单数据。
  • 典型应用场景:FormData + Ajax 技术实现文件上传的功能。
  • 作用:快速获取form标签中有name属性的表单数据
  • 语法:const form = new FormData(form标签dom元素)

文件上传

  • input标签属性:
    • type = "file"
    • accept属性:控制能够选择的文件类型,比如 accept="image/png,image/jpeg"
    • multiple 属性:控制是否可以多选文件。
  • 绑定change
  • this.files数组。
  • URL.createObjectURL(文件) 返回 src 地址。
  • 使用FormData 对象来包装要上传的数据。
  • post请求把FormData 传递给服务器。

请求报文 & 响应报文

客户端与服务器通信的过程是基于请求响应的:

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

请求报文

  • 请求报文由请求行(request line)、请求头部( header )、空行请求体 4 个部分组成。
  • 在浏览器中,GET 请求比较特殊,它只有请求头,没有请求体。
  • 在浏览器中,POST、PUT、PATCH、DELETE 请求既有请求头,又有请求体。

响应报文

  • 响应报文由状态行响应头部空行响应体 4 个部分组成。

URL参数

  • 由于URL的长度有限制,所以请求参数一般都比较小,比如不能做文件上传。
  • 常用的请求参数有两种写法:
    • 查询参数:(/api/xxx?参数=值&参数=值)
    • Restful 风格的接口:( /api/xxx/值/值)

请求体

  • 请求体的大小没有限制,所以可以提交大量的数据。

  • 常用的请求体格式有如下三种:

    • 查询字符串格式:参数=值&参数=值

      对应的请求头:application/x-www-form-urlencoded

      语法:axios.post('/api/addbook?appkey=qqq777');

    • JSON格式:'{ "id": 1, "name": "zs" }'

      对应的请求头: application/json

      语法:axios.post('/api/addbook,{id: 1, name: 'zs'}');

    • FormData对象格式:new FormData()

      对应的请求头:multipart/form-data; xxsd随机字符

      语法:let fd = new FormData() ; axios.post('/api/addbook,fd);

http响应状态码

  • 客户端浏览器根据响应状态码,即可判断出这次 http 请求是成功还是失败了。

1651150068014.png

http 响应状态码 Vs 业务状态码

  • 所处的位置:
    • 在响应头的状态行中所包含的状态码,或者请求列表中的Status,叫做“响应状态码”。
    • 在响应体的数据中所包含的状态码(案例中叫做code),叫做“业务状态码”。
  • 表示的结果:
    • 响应状态码只能表示这次请求的成功与否(成功地失败了)。
    • 业务状态码用来表示这次业务处理的成功与否。
  • 通用性不同:
    • 响应状态码是由 http 协议规定的,具有通用性。每个不同的状态码都有其标准的含义,不能乱用。
    • 业务状态码是后端程序员自定义的,不具有通用性。

XMLHttpRequest

  1. 浏览器内置的一个构造函数
  2. 基于 new 出来的 XMLHttpRequest 实例对象,可以发起 Ajax 的请求。
  3. axios 中的 axios.get()、axios.post()、axios() 方法,都是基于 XMLHttpRequest(简称:XHR) 封装出来的。
  4. 可以不用 axios 封装的 Ajax 函数,直接基于 XMLHttpRequest 发起 Ajax 请求。

使用 XMLHttpRequest 发起 GET 请求

  • 主要的 4 个实现步骤:
    • 创建 xhr 对象
    • 调用xhr.open() 函数
    • 调用xhr.send() 函数
    • 监听load事件
  • 发起 Ajax 请求的核心对象是XMLHttpRequest
  • 拿到服务器响应回来的数据:load事件、xhr.response
  • send() 专门用来发出ajax网络请求。
  • open() 可以用来指定ajax的请求类型和请求url
  • URLSearchParams:把data 转成 a=b&c=d

数据交换格式

  • 数据交换格式,就是服务器端客户端之间数据传输的格式。
  • 两种数据交换格式:JSON(主流)、XML(少用)
  • JSON(全称:JavaScript Object Notation)是一种数据交换格式,它本质上是用字符串的方式来表示对象数组类型的数据。

JSON数据

  • 用字符串的方式来表示的对象数组类型的数据,叫做 JSON 数据。
  • JSON数据格式:对象格式、数组格式。
  • JSON 的语法要求:
    • 属性名必须使用双引号包裹。
    • 字符串类型的值必须使用双引号包裹。
    • JSON 中不允许使用单引号表示字符串。
    • JSON 中不能写注释。
    • JSON 的最外层必须是对象或数组格式。
    • 不能使用 undefined 或函数作为 JSON 的值。

对象格式的JSON数据

  • 对象格式的 JSON 数据,最外层使用 { } 进行包裹,内部的数据为 "key": "value" 的键值对结构:
    • key 必须使用英文的双引号进行包裹。
    • value 的值只能是字符串、数字、布尔值、null、数组、对象类型(可选类型只有这 6 种)

数组格式的 JSON 数据

  • 数组格式的 JSON 数据,最外层使用 [ ] 进行包裹,内部的每一项数据之间使用英文的 , 分隔。
    • 每一项的值类型只能是字符串、数字、布尔值、null、数组、对象这 6 种类型之一。

把 JSON 数据转换为 JS 数据

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

    <script>
        //输出对象 {a: 'hello', b: 'world'}
        const jsonObj='{"a":"hello","b":"world"}'
        console.log(JSON.parse(jsonObj));
        
        //输出数组 ['java','hello','js']
        const jsonArr = '["java","hello","js"]'
        console.log(JSON.parse(jsonArr));
    </script>
    

把 JS 数据转换为 JSON 数据

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

    <script>
        //输出JSON对象 {"name":"hel","age":22}
        const user='{name:'hel',age:22}'
        console.log(JSON.stringify(user));
        
        //输出JSON数组 ["java","hello","js"]
        const list = '['java','hello','js']'
        console.log(JSON.stringify(list));
    </script>
    

序列化

  • 序列化:把对象或者数组 转成 字符串格式。JSON.stringify();
  • 反序列化:把字符串格式 转成 对象或者数组。JSON.parse();
  • 调用 JSON.parse() 函数将 xhr.response 把 XMLHttpRequest 请求到的 JSON 数据反序列化为 JS 对象。

封装自己的 Ajax 函数

  1. 如何判断一个对象是否为某个构造函数的实例?
    • 对象 instanceof 构造函数
    • 简化:if (options.data instanceof FormData) return xhr.send(options.data)
  2. 如何判断某个值是否为字符串类型?
    • typeof 值 === 'string'
  3. 如何判断某个值是否为对象类型?
    • typeof 值 === 'object'

同源策略 & 跨域

同源

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

同源策略

  • 同源策略(全称 Same origin policy)是浏览器提供的一个安全功能。
  • 浏览器的同源策略规定:不允许非同源的 URL 之间进行资源的交互。

跨域

  • 同源指的是两个 URL 的协议、主机名、端口号完全一致,反之,则是跨域。
  • 出现跨域的根本原因:浏览器的同源策略不允许非同源的 URL 之间进行资源的交互。

浏览器对跨域请求的拦截过程

  • 突破浏览器跨域限制的两种方案:

    • JSONP(非官方):兼容性好,仅支持GET请求。

    • CORS(W3C官方标准):支持GET、POST、PUT、DELETE、PATCH等常见的请求方式。

    • CORS 技术需要浏览器和服务器同时支持,二者缺一不可。实现 CORS 的关键,在服务器端

防抖 & 节流

防抖

  • 防抖(debounce)指的是:频繁触发某个操作时,只执行最后一次。

    <script>
    // change事件 输入框的值发生改变,输入框失去焦点才触发
    // input 事件
    // 定义一个延时定时器
       let timeid;
       let input = document.querySelector('input');
       input.addEventListener('input', function (event) {
            clearTimeout(timeid);
            // 开启了一个延时器 里面代码 1s后会执行
            timeid = setTimeout(function () {
                // 获取输入框的值
                // trim() 去除 输入框的值 的两侧的 空字符串
                const value = input.value.trim();
                const queryStr = `?bookname=${value}`;
                getData(queryStr); // 把参数带过去
            },1000);
        });
    </script>
    

节流

  • 节流(throttle)指的是:单位时间内,频繁触发同一个操作,只会触发 1 次。

    <script>
        let isLoadding = false; //有没有请求在发送当中
        // 点击按钮的时候先判断 isLoadding true还是false
        //  true 请求在发送中 return  false 没有请求
        //   先设置 isLoadding true
        //   发送请求出去 请求回来了  设置 isLoadding = false
     document.querySelector('button').addEventListener('click', function () {
            if (isLoadding) {
                return;
            }
            isLoadding = true; 
            // this.disabled=true; //发送请求的时候  禁用按钮
            getData();
        });
        function getData(query = '') {
            console.log('请求发送出去');
            axios({
                method: 'get',
                url: 'http://www.itcbc.com:3006/api/getbooks' + query,
                // params:{
                //     appkey: 'qqq777'
                // },
            }).then((result) => {
                console.log('数据回来了');
                isLoadding = false;
            });
        }
    </script>