AJAX 基础

AJAX

1、AJAX定义与axios使用

定义: AJAX(Asynchronous Javascript And XML),即异步的JavaScript和XML,是浏览器与服务器进行数据通信的技术。

axios示例:

<body>
    <div class="province-list"></div>

    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script>
        axios({
        url: "http://hmajax.itheima.net/api/province"
    }).then(result=>{
        console.log(result.data.list.join("<br>"));
        document.querySelector(".province-list").innerHTML = result.data.list.join("<br>")
    })
    </script>
</body>

2、URL

2.1 URL简介

定义:URL(Uniform Resource Locator),称为统一资源定位符或网址

URL示例:http://www.bilibili.com/v/douga/

示例名称作用
http://协议规定浏览器和服务器之间传输数据的格式
www.bilibili.com/域名标记服务器在互联网中的位置(确定要访问的服务器)
v/douga/资源路径标记资源在服务器上的具体位置
2.2 URL查询参数

定义:浏览器提供给服务器的额外信息,让服务器返回浏览器想要的数据

语法:http://xxxx.com/xxx/xxx?参数1=值1&参数2=值2

查询参数示例:

<body>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script>
        axios({
            url:"http://hmajax.itheima.net/api/city",
            params:{                       // 查询参数写在此处
                pname : '湖南省',
            }
        }).then(res =>{
            console.log(res.data.list);
        })
    </script>
</body>
2.3 常用请求方法

请求方法:对服务器的资源,要采取的操作

请求方法操作
GET获取数据(默认方式,不区分大小写)
POST提交数据
PUT修改数据(全部)
DELETE删除数据
PATCH修改数据(部分)

POST用于注册示例:

<body>
    <button class="btn">注册</button>

    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script>
        document.querySelector('.btn').addEventListener('click', () =>{
            axios({
                url : "http://hmajax.itheima.net/api/register",
                method : 'post',
                data : {
                    username : 'wqwe1234_',
                    password : '1234556'
                }
            }).then(res => {
                console.log(res);
            })
        })
    </script>
</body>

3、axios错误处理

使用关键字catch捕获

<body>
    <button class="btn">注册</button>

    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script>
        document.querySelector('.btn').addEventListener('click', () =>{
            axios({
                url : "http://hmajax.itheima.net/api/register",
                method : 'post',
                data : {
                    username : 'wqwe12322_',
                    password : '1234556'
                }
            }).then(res => {
                console.log(res);
            }).catch(error=>{      // 使用catch捕获异常
                console.log(error);
                alert(error.response.data.message)
            })
        })
    </script>
</body>

4、HTTP协议

HTTP协议规定了浏览器发送及服务器返回内容的格式

4.1 请求报文

请求报文: 浏览器发送给服务器的内容

组成:

名称示例作用
请求行POST /api/register HTTP/1.1请求方式、请求地址、协议
请求头Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: keep-alive
Content-Length: 46
Content-Type: application/json
Host: hmajax.itheima.net
Origin: null
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
以键值对的格式携带的附加信息,如Content-Type
请求体{“username”:“wqwe12322_”,“password”:“1234556”}请求的信息

通过谷歌浏览器网络面板查看请求报文
在这里插入图片描述
错误排查:通过请求报文排查错误原因,并修复

4.2 响应报文

**响应报文:**服务器按照HTTP协议要求的格式,返回给浏览器的内容

组成:

名称示例作用
响应行HTTP/1.1 400 Bad Request协议、HTTP协议响应状态码、状态信息
响应头Date: Thu, 12 Oct 2023 12:06:55 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 54
Connection: keep-alive
Set-Cookie: acw_tc=2f624a51d;path=/;HttpOnly;Max-Age=1800
Server: nginx
Vary: Origin
Access-Control-Allow-Origin: null
Access-Control-Allow-Credentials: true
Accept-Ranges: bytes
x-frame-options: SAMEORIGIN
x-xss-protection: 1; mode=block
x-content-type-options: nosniffv
x-download-options: noopen
x-readtime: 9
以键值对的格式携带的附加信息,如Content-Type
空行分隔响应头,空行之后是返回给浏览器的资源
响应体{“code”:10005,“message”:“账号被占用”,“data”:null}返回的资源

HTTP协议响应状态码

状态码说明
1XX信息
2XX成功
3XX重定向消息
4XX客户端错误
5XX服务端错误
4.3 接口文档

接口文档:描述接口的文章

接口:使用AJAX和服务器通讯时,使用的URL、请求方法、参数

5、form-serialize收集表单信息

语法:data = serialize**(form**, {hash:true, empty:true})。 使用时,要给表单添加

参数取值解释
form要获取数据的表单
hashtrue、falsetrue:返回JS对象
false:查询字符串
emptytrue、false是否获取空值

示例:

<body>
    <form class="infor" action="javascript:;">
        <span>name:</span>
        <input type="text" name="username">     <!-- 使用时,要给表单添加  -->
        <span>password:</span>
        <input type="passsword" name="password">
        <button>提交</button>
    </form>
    <script src="./lib/form-serialize.js"></script>
    <script>
        document.querySelector('button').addEventListener('click',()=>{
            const form = document.querySelector('.infor')
            const data = serialize(form, {hash:true, empty:true})
            console.log(data)
        })
    </script>
</body>

6、bootstrap弹窗使用

官网示例:

<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Bootstrap 弹框</title>
  <!-- 引入bootstrap.css -->
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
</head>

<body>
  <button type="button" class="btn btn-primary change-btn" data-bs-toggle="modal" data-bs-target=".box">编辑姓名</button> 
   <div class="modal box" tabindex="-1">
    <div class="modal-dialog">
      <div class="modal-content">
        <div class="modal-header">
          <h5 class="modal-title">请输入姓名</h5>
          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
        </div>
        <div class="modal-body">
            <form action="javascript:;">
                <span>姓名:</span>
                <input type="text" class="username">
            </form>
          
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
          <button type="button" class="btn btn-save btn-primary">保存</button>
        </div>
      </div>
    </div>
  </div>
  
  <!-- 引入bootstrap.js -->
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.min.js"></script>
  <script>
    let box = document.querySelector('.box')
    let mybox = new bootstrap.Modal(box)


    document.querySelector('.change-btn').addEventListener('click', ()=>{
        mybox.show()
    })

    document.querySelector('.box .btn-save').addEventListener('click', ()=>{
            const username = document.querySelector('.box .username').value
            console.log(username)
            mybox.hide()
        })
  </script>
</body>
</html>

使用步骤:

1、引入官方CSS和JS

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.min.js"></script>

2、CSS控制弹窗的显示和关闭

<!-- 显示:给控制显示弹窗的按钮添加两个自定义属性 data-bs-toggle="modal" data-bs-target=".box" -->
<button type="button" class="btn btn-primary change-btn" data-bs-toggle="modal" data-bs-target=".box">编辑姓名</button> 

<!-- 关闭:给控制关闭弹窗的按钮添加自定义属性 data-bs-dismiss="modal"-->
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>

3、通过JS控制弹窗的出现和关闭

let box = document.querySelector('.box')
let mybox = new bootstrap.Modal(box)

mybox.show()  // 显示
mybox.hide()  // 关闭

7、XMLHttpRequest对象使用

7.1 XMLHttpRequest基本使用

XMLHttpRequest对象用于与服务器交互,是AJAX的基本原理;也是axios的内部实现原理。

使用步骤:

  1. 创建XMLHttpRequest对象
  2. 调用open方法,配置请求方法和URL
  3. 监听loadend事件,接收响应结果
  4. 调用send方法,发起请求
<!--省份渲染 -->
<body>
    <div>
        <ul class="provience">
            <li></li>
        </ul>
    </div>
    <script>
        const xhr = new XMLHttpRequest()                                     // 1、创建XMLHttpRequest对象
        xhr.open('GET','https://hmajax.itheima.net/api/province')            // /2、配置请求方法和URL,

        xhr.addEventListener('loadend',res => {                              // 2、监听loadend事件,接收响应结果
            const data = JSON.parse(xhr.response)                // 返回位JASON字符串,需要转为对象
            const str_data = data.list.map(ele => { return `<li>${ele}</li>`})
            document.querySelector('.provience').innerHTML = str_data.join(' ')
        })
        xhr.send()                                                            // 4、发起请求
    </script>
</body>
7.2 XMLHttpRequest查询参数
<body>
    <div>
        <ul class="city">
            <li></li>
        </ul>
    </div>
    <script>
        const xhr = new XMLHttpRequest()
        xhr.open('GET',"https://hmajax.itheima.net/api/city?pname=湖南省")   // ?后为携带的查询参数
        xhr.addEventListener('loadend', () => {
            const data = JSON.parse(xhr.response)
            const str_data = data.list.map(item => { return `<li>${item}</li>`})
            document.querySelector('.city').innerHTML = str_data.join('')
        })
        xhr.send()
    </script>
</body>
7.3 URLSearchParams使用

作用: 将JS对象转换为URL查询参数

const city_infor = {
    pname:'贵州省',
    cname:'贵阳市'
}
const param = new URLSearchParams(city_infor)
const string_param = param.toString()

8、Promise

Promise对象用于表示一个异步操作最终完成(或失败)及其结果值。

语法:

// 创建promise对象
const p = new Promise((resolve, reject) => {
// 执行异步任务,并且传递结果
    // 成功调用:resolve()触发then()执行
    // 失败调用:reject()触发catch()执行
})
// 接收结果
p.then(res => {
    // 成功
}).catch(error => {
    // 失败
})
8.1 实现axios函数
function myAxios(config)
{
  return new Promise((resolve,reject) => {
    const xhr = new XMLHttpRequest()
    if(config.params)
    {
      const param = new URLSearchParams(config.params)
      const str_param = param.toString()
      config.url += `?${str_param}`
    }
    xhr.open(config.method || 'GET', config.url)

    xhr.addEventListener('loadend', () => {
      if(xhr.status >= 200 && xhr.status < 300)
      {
        resolve(JSON.parse(xhr.response))
      }
      else
      {
        reject(new Error(xhr.response))
      }
    })

    if(config.data)
    {
      xhr.setRequestHeader('Content-Type','application/json')
      const str = JSON.stringify(config.data)
      xhr.send(str)
    }
    else{
      xhr.send()
    }
  })
}
8.2 Promise.all静态方法

概念:合并多个Promise对象,等待所有对象同时完成(或某一个失败),然后执行后序逻辑

<script>
	const p = Promise.all([Promise对象1, Promise对象2,,....])
	p.then(res => {
        // 所有Promise对象都获取信息成功
    }).catch(error => {
        // 某个Promise对象获取信息失败
    })
</script>

9、同步代码&异步代码、回调函数

9.1 同步异步&异步代码

同步代码:逐行执行,原地等待结果后,才继续向下执行

异步代码:调用后耗时,不阻塞代码执行,将来完成后触发回调函数

JS中的异步代码:setTimeout/setInterval、事件、AJAX

9.2 回调函数地狱

定义:在回调函数内一直向下嵌套回调函数

// 示例
<body>
    <form action="javascript:;">
        省份: <select>
            <option value="" class="provience"></option>
        </select>
        城市: <select>
            <option value="" class="city"></option>
        </select>
        地区: <select>
            <option value="" class="area"></option>
        </select>
    </form>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
	<script>
        axios({url : 'https://hmajax.itheima.net/api/province'}).then(res1 =>{    // 回调函数地域
            const pname = res1.data.list[0]
            document.querySelector('.provience').innerHTML = pname
            axios({url : 'https://hmajax.itheima.net/api/city',params : {pname}}).then(res2 => {
                const cname = res2.data.list[0]
                document.querySelector('.city').innerHTML = cname
                axios({url : 'https://hmajax.itheima.net/api/area', params : {pname, cname}}).then(res3 => {
                    const area = res3.data.list[0]
                    document.querySelector('.area').innerHTML = area
                })
            })
        })  
	</script>
</body>

问题:

  • 可读性差
  • 异常难以捕获
  • 耦合性严重

解决方法:

  • promise链式调用

​ 使用then函数返回新的Promise对象特性,一直串联下去

​ then回调函数中,return的值会传给then函数新生成的Promise对象

// 示例
<body>
    <form action="javascript:;">
        省份: <select>
            <option value="" class="provience"></option>
        </select>
        城市: <select>
            <option value="" class="city"></option>
        </select>
        地区: <select>
            <option value="" class="area"></option>
        </select>
    </form>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
 	<script>
        let pname = ''
        axios({url : 'https://hmajax.itheima.net/api/province'}).then(res1 =>{    
            pname = res1.data.list[0]
            document.querySelector('.provience').innerHTML = pname
            return axios({url : 'https://hmajax.itheima.net/api/city',params : {pname}}).then(res2 => {
                const cname = res2.data.list[0]
                document.querySelector('.city').innerHTML = cname
                return axios({url : 'https://hmajax.itheima.net/api/area', params : {pname, cname}}).then(res3 => {
                    const area = res3.data.list[0]
                    document.querySelector('.area').innerHTML = area
                })
            })
        }).catch(error => {
            console.log(error);
        })     
    </script>
</body>
  • 使用async和await
<body>
    <form action="javascript:;">
        省份: <select>
            <option value="" class="provience"></option>
        </select>
        城市: <select>
            <option value="" class="city"></option>
        </select>
        地区: <select>
            <option value="" class="area"></option>
        </select>
    </form>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script>
        async function getData()
        {
            try{
                const p_obj = await axios({url : 'https://hmajax.itheima.net/api/province'})
                const pname = p_obj.data.list[0]
                const c_obj = await axios({url : 'https://hmajax.itheima.net/api/city',params : {pname}})
                const cname = c_obj.data.list[0]
                const a_obj = await axios({url : 'https://hmajax.itheima.net/api/area1', params : {pname, cname}})
                const area = a_obj.data.list[0]

                document.querySelector('.provience').innerHTML = pname
                document.querySelector('.city').innerHTML = cname
                document.querySelector('.area').innerHTML = area
                
            }catch(error){
                console.dir(error.response);
            }
        }
        getData()
    </script>
</body>

10、事件循环(EventLoop)

事件循环: 执行代码和收集异步任务,在调用栈空闲时,反复调用队列里的回调函数执行机制

事件循环作用:JavaScript是单线程的,为了不阻塞JS引擎,设计了事件循环用于处理异步任务

JS代码执行过程:

  • 执行同步代码,遇到异步代码交给宿主浏览器环境执行
  • 异步有了结果后,把回调函数放入任务队列排队
  • 当调用栈空闲后,反复调用任务队列里的回调函数
10.1 宏任务与微任务

宏任务:浏览器环境执行的异步代码

微任务:JS引擎环境执行的异步代码

任务(代码)执行所在环境
JS脚本执行事件(script)浏览器
setTimeout/setInterval浏览器
AJAX请求完成事件浏览器
用户交互事件浏览器
Promise对象.then()JS引擎

同时有宏任务和微任务在队列时,先执行微任务(清空微任务队列)再执行宏任务。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值