ajax的第四天(一)

106 阅读4分钟

ajax的第四天

formdata对象 ,input的flie change this.files accept

    <input type="file" accept="image/*" />
    <script src="./lib/axios.js"></script>
    <script>
      /* 
      文件上传 
      1 fomdata对象 
      2 input file change this.files  accept
      3 axios
      
       */
      const input = document.querySelector('input');
      input.addEventListener('change', function () {
        // console.log("文件加载到浏览器内存中了");
        // console.log(this.files);
        const file = this.files[0];
        const formdata = new FormData();
        // 接口要求 键值对的
        formdata.append('avatar', file);

        axios
          .post('http://www.itcbc.com:3006/api/formdata', formdata)
          .then((result) => {
            console.log(result);
          });
      });
    </script>

请求报文和响应报文

什么是请求报文

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

1.请求报文:请求行,请求头,空行和请求体4个部分组成

响应报文

响应报文-格式

响应报文由状态行、响应头部、空行 和 响应体 4 个部分组成。图示如下:

connection 头(header) 决定当前的事务完成后,是否会关闭网络连接。

URL参数

  • 常用的5种请求方式,都可以在URL后面携带请求参数。

  • 由于URL的长度有限制,所以请求参数一般都比较小,比如不能做文件上传

  • 常用的请求参数有两种写法

  • /api/xxx?参数=值&参数=值

    (这种格式的字符串叫做查询字符串,所以这样的参数叫做查询参数)

  • /api/xxx/值/值

    (Restful 风格的接口用这种格式的参数)

<script>
    	//写法1 get(URL)
      axios.get("http://www.itcbc.com:3006/api/getbooks?appkey=HZD123")
      	.then((result)=>{
            console.log(result);
        })
        
    //写法2 get(URL,{params:参数})
      axios.get("http://www.itcbc.com:3006/api/getbooks",{params:{appkey:`HZD123`}})
        .then((result)=>{
            console.log(result);
        })

</script>
请求体

本质:除了GET请求以外,其他4种常用的请求方式,都可以设置请求体

作用:请求体大小没有限制,所以可以提交大量的数据

请求体

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

  1. 第一种格式:参数=值&参数=值 Content-type:application/x-www-form-urlencoded

  2. 第二种格式: '{ "id": 1, "name": Content-type:application/json

  3. 第三种格式: new FormData() Content-type:multipart/form-data; xxsd 随机字符

<script>
  // 写法1 axios.post(url,参数(对象))
  axios.post("http://www.itcbc.com:3006/api/addbook?appkey=HZD123",{bookname:`民族`,appkey:`XXX`})
            .then((result)=>{
            console.log(result);
        })

 // 写法2 axios.post(url,参数(字符串))
 axios.post("http://www.itcbc.com:3006/api/addbook?appkey=HZD123",`bookname=sf&appkey=XXX`)
            .then((result)=>{
            console.log(result);
        })
    
 // 写法3
 axios.post(`http://www.itcbc.com:3006/api/formdata`
            ,formdata)
     		.then((result)=>{
            console.log(result);
        })
</script>

http 响应状态码

本质:http响应状态码由三位数字组成,用来标识响应成功与否的状态

作用:客户端浏览器根据响应状态码,即可判断这次http请求是否成功

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

本质:所处的位置,表示的结果,通用性不同

1.所处的位置不同

在响应头的状态行中所包含的状态码,或者请求列表中的Status

  • 业务状态码在响应体的数据中所包含的状态码,如案例中的code

  • 表示的结果

    响应状态码只能表示这次请求的成功与否(成功地失败了)

    业务状态码用来表示这次业务处理的成功与否

  • 通用性

    响应状态码是由 http 协议规定的,具有通用性。每个不同的状态码都有其标准的含义,不能乱用。

    业务状态码是后端程序员自己定义的,不具有通用性(如聚合,天行,百度等API的接口)

    HTTTP 状态码分类

XMLHTTpRequest

本质:是浏览器内置的一个构造函数

作用

1.基于new出来的XHR实例对象,可以发起Ajax的请求。

2.axios中的axios.get() .post()等方法都是基于XHR来的,XHR是原生(底层)代码

主要 的四个实现步骤;

​ 1 .创建xhr 对象

  1. 调用open()函数

  2. 调用send() 函数

  3. 监听load 事件

        <script>
          // 1 创建 xhr对象
          const xhr = new XMLHttpRequest();
          // 2 调用 open方法 指定 请求类型,url
          xhr.open('get', 'http://www.itcbc.com:3006/api/getbooks');
          // 3 发送出去 send
          xhr.send();
          // 4 监听onload  数据响应事件
          xhr.addEventListener('load', function () {
            // this
            console.log('数据回来啦');
            // console.log(this.response);
            // 字符串转对象
            const obj = JSON.parse(this.response);
            console.log(obj);
          });
          // axios.get("http://www.itcbc.com:3006/api/getbooks")
          // .ten(result)
        </script>
    
请求时携带URL参数
  • URL参数 ,只能拼在URL地址后面
  • 请求题 放在 send()里面
  • 由于URL的长度有限制,所以请求参数一般都比较小,比如不能做文件上传
  • 常用的请求参数有两种写法- - /api/xxx?参数=值&参数=值 (这种格式的字符串叫做查询字符串,所以这样的参数叫做查询参数) - /api/xxx/值/值 (Restful 风格的接口用这种格式的参数) axios中 如何携带不同格式的请求参数 第一种格式的参数:(/api/xxx?参数=值&参数=值)
	axios.get('/api/xxx?key=value&key=value')
	//按照axios的语法写,axios会帮我们转成查询字符串
   axios.get('api/xxx',{
       params:{
           key:value,
       }
           
   })

第二种格式的参数:( /api/xxx/值/值)
axios.get('/api/xxx/100/ss')

除GET请求以外,其他4种常用的请求方式,都可以设置请求体。

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

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

  • 参数=值&参数=值 (查询字符串格式)
  • '{ "id": 1, "name": "zs" }' (JSON格式)
  • new FormData() (FormData对象格式)

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

Content-Type: application/x-www-form-urlencoded 参数=值&参数=值

    <script>
        const xhr =new XMLHttpRequest();
        xhr.open('post','http://www.itcbc.com:3006/api/addbook');
        
        const data ={
            bookname:'从入门到家京',
            author:'dsf',
            pulisher:'合并',
            appkey:'wanshao1234',
            }
            const usp =new  URLSearchParams(data);
            const query = usp.toString();

            xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
            xhr.send(query);

            xhr.addEventListener('load',function(){
                console.log(this.response);
            })
  </script>

字符串格式

Content-Type: application/json '{ "id": 1, "name": "zs" }'

    <script>
        const xhr = new XMLHttpRequest();
        xhr.open('post','http://www.itcbc.com:3006/api/addbook')
        const data = {
            bookname: '2从入门到精通2',
            author: '我自己',
            publisher: '黑马出版社',
            appkey: 'wanshao1234',
        };

        xhr.setRequestHeader('Content-type','application/json');
        const str = JSON.stringify(data);
        xhr.send(str);
        xhr.addEventListener('load',function(){
            console.log(this.response);
        })
  </script>

FormData形式

Content-Type: multipart/form-data; xxsd随机字符 new FormData()

   <input type="file" name="" accept="images/*" id="">
    <script>
        const input = document.querySelector('input')
        input.addEventListener('change',function(){

            const file =this.files[0];
            const formdata =new FormData();
            formdata.append('avatar',file);
            const xhr = new XMLHttpRequest();
            xhr.open('post','http://www.itcbc.com:3006/api/formdata');
            xhr.send(formdata)
            xhr.addEventListener('load',function(){
                console.log(this.response);
            })
        })
    </script>

自封装Ajax

1.根据JQ的Ajax出发,封装属于自己的Ajxa

<script>
    // JQ的代码也是通过封装的 我们跟着这个代码思路自封装
    $.ajax({
            url: `http://www.itcbc.com:3006/api/getbooks`,
            type: `get`,
            data: `appkey=HZD123`,
            success(result) {
                console.log(result);
            }
        })
    
    const option = {
            url: `http://www.itcbc.com:3006/api/getbooks`,
            type: `get`,
            data: `appkey=HZD123`,
            success(result) {
                console.log(result);
            }
        }
        // 我们自己封装一个Ajax函数 来实现ajax上传功能
        ajax(option) // 这是一个函数 调用option里面的属性 实现上传
</script>

2.实现第一步功能 GET 方式 不携带参数

<script>
	function ajax(config) {
            const xhr = new XMLHttpRequest()
            // 因为 元素 Ajxa get 请求 携带参数 只能拼接在 URL 后
            xhr.open(config.type, config.url + `?` + config.data)
            xhr.send()
            xhr.addEventListener(`load`, function () {
                //this.response = 上传的返回值转对象后 = option.success(result)
                const obj = JSON.parse(this.response)
                config.success(obj)
            })
        }
</script>


3.当GET方式 携带参数

<script>
        function ajax({type,url,data=``,success}) {
            const xhr = new XMLHttpRequest()
            xhr.open(type, url + `?` + data)
            xhr.send()
            xhr.addEventListener(`load`, function () {
                const obj = JSON.parse(this.response)
                success(obj)
            })
        }
</script>

4.当GET方式中 data是不同类型时

<script>
	function ajax({ url, type, data = ``, success }) {
            const xhr = new XMLHttpRequest()
            if (typeof data === `object`) {
		data = (new URLSearchParams(data)).toString()
            }
            xhr.open(type, url + `?` + data)
            xhr.send()
            xhr.addEventListener(`load`, function () {
                const obj = JSON.parse(this.response)
                success(obj)
            })
        }
</script>

5.封装POST 方式

判断当前data数据类型:字符串、对象、FormData(之前内容)

<script>
    function ajax({ url, type, data = ``, success }) {
            const xhr = new XMLHttpRequest()
            // get请求类型
            if (type === `get`) {
                if (typeof data === `object`) {
                    data = (new URLSearchParams(data)).toString()
                }
                xhr.open(type, url + `?` + data)
                xhr.send()
                // post请求类型
            } else if (type === `post`) {
                xhr.open(type, url)
                // 判断是不是字符串
                if (typeof data === `string`) {
				xhr.setRequestHeader(`Content-type`, `application/x-www-form-urlencoded`)
                    xhr.send(data)
                    // 判断是不是对象(普通对象和FormData)
                } else if (typeof data === `object`) {
          // 判断 实例和构造函数的关系 实例 instanceof 构造函数 
                    if (data instanceof FormData) {
                        xhr.send(data)
                    } else {
                        xhr.setRequestHeader(`Content-type`, `application/json`)
                        const str = JSON.stringify(data)
                        xhr.send(str)
                    }
                }
            }
</script>

总结:

1.通过今天所学的底层原生Ajax 代码 来封装一个 自己的Ajax上传函数 用JQ的Ajax做参考

2.参照JQ的ajxa代码格式 运用底层的原生Ajax 进行封装使用

3.有传参和不传参两种情况 用默认值+解构思路 进一步优化代码

4.最后把形参.属性名 优化 解构{属性名,data=``(默认值)}

5.data可以是没有参数 可以是字符串 还可以是对象

6.type of 判断是否为对象 运用URLsearcParams/ .toString()转换数据

7.post请求方式 与get不同 所以用if区分 get一部分 post 一部分

8.判断当前data数据类型:字符串、对象、FormData 分别放入相应判断函数内

9.判断字符串类型: typeof 判断实例对应构造函数: 实例 instanceof 构造函数

JSON

JSON(全称:JavaScript Object Notation)是一种数据交换格式,它本质上是用字符串的方式来表示对象或数组类型的数据。例如:

//字符串的方式表示的【对象格式
const obj ='{"name","zs","age":20,"gender":true}',

const arr ='["java","js","javaScript"]'

1对象格式 2 数组格式

使用 JSON 定义 JSON 格式的数据时,要遵守以下的 6 条规则:

  • 属性名必须使用双引号包裹

  • 字符串类型的值必须使用双引号包裹

  • JSON 中不允许使用单引号表示字符串

  • JSON 中不能写注释

  • JSON 的最外层必须是对象或数组格式(其他类型也可以,但多数是对象或数组格式)

  • 不能使用 undefined 或函数作为 JSON 的值

    对象格式的 JSON 数据

    key必须使用英文的双引号进行包裹

    value的值只能是字符串、数字、布尔值、null、数组、对象类型(6)

    数组格式的JSON数据

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

    const arr= '["da","cc"]'
    

    把 JSON 数据转换为 JS 数据

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

    const jsonObj ='{"a":"hellow"}'
    
    

    把 JS 数据转换为 JSON 数据

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

    const usr ={name:'24',age:20}
    console.log(JSON.stringify(user))
    
    const list =['html','css','js']
    console.log(JSON.stringify(list))
    
什么是数据交换格式

把真实数据转换为字符串的过程,叫做序列化

把字符串转换为真实数据的过程,叫做反序列化

把 XMLHttpRequest 请求到的 JSON 数据反序列化为 JS 对象

在 xhr 对象的 load 事件中,通过 xhr.response 访问到的是 JSON 格式的字符串数据。可以调用 JSON.parse() 函数将 xhr.response 转化为 JS 对象。示例代码如下:

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

节流

什么是节流?

单位时间内,控制执行的次数,也就是减少一段时间的触发频率

节流的好处

同样是为了减轻服务器的压力

代码示范:

    <button>获取数据</button>
    <script src="./lib/axios.js"></script>
    <script>
      /* 
      节流
      上一次的业务没有结束的话 不允许开启下一次业务
      使用场景 移动端分页  -  倒计时按钮 等等 
      
       */
      // 这一次请求还没有结束 就不能开启下一个请求
      // 业务 分页 业务

      // 开关
     let isLoading = false;  //有没有请求在发送中
           // 点击按钮的时候先判断 isLoadding true还是false
      //  true 请求在发送中  return
      //  false 没有请求
      //   先设置 isLoadding true
      //   发送请求出去
      //  请求回来了  设置 isLoadding = false
     document.querySelector('button').addEventListener('click',function(){
         if(isLoading){
            return;
         }
         isLoading =true;

         getData();
     });
     
     function getData(query = ''){
        console.log('请求发送出去');
        axios({
            method: 'get',
            url: 'http://www.itcbc.com:3006/api/getbooks' + query,

        }).then((result)=>{
            console.log('数据回来了');
            isLoading = false;
        })
     }  

    </script>

防抖

本质:指的是频繁触发某一个操作,只能执行最后一次

<script>
  	//设置开关
	let timeId
        keyword.addEventListener(`input`, function (e) {
            clearTimeout(timeId)
            timeId = setTimeout(function () {
                let value = keyword.value.trim()
                let valuePush = `?bookname=${value}`
                getData(valuePush)
            }, 1000)
        })
</script>

原生ajax用get方式获取图片管理书籍

![微信截图_20220430011356](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/23a4dfc42ebb4c4e910ed228d5de2b3e~tplv-k3u1fbpfcp-zoom-1.image)
    <script>
        // 1.创建xhr对象
        // 2.调用open方法 指定 请求类型 url
        // 3. 发送请求 send
        // 4.监听 onload 数据响应事件
        // 字符串转对象
        // http://www.itcbc.com:3006/api/getbooks  get
        const xhr = new XMLHttpRequest();       		        xhr.open('get',                                              'http://www.itcbc.com:3006/api/getbooks')
        xhr.send();
        xhr.addEventListener('load',function(){
            // this    response
            const obj = JSON.parse(this.response)
            console.log(obj);
        })
    </script>