【三】Ajax与异步编程之数据传输格式ajax

发布时间 2023-07-16 15:47:24作者: Chimengmeng

【三】Ajax与异步编程之数据传输格式ajax

【1】什么是ajax

  • ajax,一般中文称之为:"阿贾克斯",是英文 “Async Javascript And Xml”的简写

    • 译作:异步js和xml传输数据技术。
  • ajax的作用:

    • ajax可以让js代替浏览器向服务端程序发送http请求,与服务端进行数据通信,在用户不知道的情况下操作数据和信息,从而实现页面局部刷新数据/无刷新更新数据。
  • 所以开发中ajax是很常用的技术,主要用于操作服务端提供的数据接口,从而实现网站的前后端分离

  • ajax技术的原理是实例化js的全局对象XMLHttpRequest,使用此对象提供的内置方法就可以与服务端进行http数据通信。

【2】数据接口

  • 数据接口,也叫api接口,表示服务端提供操作数据/功能的url地址给客户端使用。

  • 客户端通过发起请求向服务端提供的url地址申请操作数据【操作一般为:增删查改】

  • 同时在工作中,大部分数据接口都不是手写,而是通过函数库/框架来自动生成的。

【3】前后端分离

  • 在开发Web应用中,有两种应用模式:

  • 前后端分离

  • 前后端不分离

【4】基本使用

  • ajax的使用必须与服务端程序配合使用
    • 但是开发中我们对于ajax请求的数据,不仅仅可以是自己写的服务端代码,也可以是别人写好的数据接口进行调用。
接口 地址
天气接口 http://wthrcdn.etouch.cn/weather_mini?city=城市名称
音乐接口搜索 http://msearchcdn.kugou.com/api/v3/search/song?keyword=歌曲标题
音乐信息接口 http://mobileservice.kugou.com/api/v3/lyric/search?version=9108&highlight=1&keyword=歌曲标题&plat=0&pagesize=20&area_code=1&page=1&with_res_tag=1
  • 原生js提供了不同的方式,允许前端开发者调用ajax。编写代码获取接口提供的数据:

方式1,基于XMLHttpRequest,实现ajax1.0

  • 代码:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
    .data-table{
        border-collapse: collapse;
        width: 800px;
        display: none;
    }
    .data-table td, .data-table th{
        font-weight: normal;
        border:1px solid red;
        text-align: center;
        width: 200px;
    }
    </style>
</head>
<body>
<input type="text" name="city" value="北京" placeholder="请输入一个国内的城市名称"><button>获取天气</button>
<table class="data-table">
    <tr>
        <th>日期</th>
        <th>类型</th>
        <th>风力</th>
        <th>温度</th>
    </tr>
</table>
</body>
<script>
    var btn = document.querySelector("button")
    var city = document.querySelector('input[name="city"]')
    let data = document.querySelector(".data-table")
    let old_conent = data.innerHTML // 原来的内容

    btn.addEventListener("click", get_weather)

    function get_weather(){
        // 原生js的ajax: 基于XMLHttpRequest实现ajax1.0版本,有5个步骤
        // 1. 创建ajax对象
        var xhr = new XMLHttpRequest()
        // console.log(xhr.readyState)  // 0
        // 2. 打开网络请求
        // 参数1:method,http请求,默认XMLHttpRequest只实现了get与post请求
        // 参数2:url,请求的资源路径,可以携带查询字符串
        xhr.open("get", `http://wthrcdn.etouch.cn/weather_mini?city=${city.value}`)
        // console.log(xhr.readyState)  // 1
        // 3. 发送网络请求
        // 参数1:可选参数,如果是post请求,则填写请求体
        //       请求体必须按查询字符串格式编写,属性=值&属性=值&属性=值.....
        xhr.send()
        // 4. 监听http通信状态
        xhr.onreadystatechange = ()=>{
            // 4.1 判断ajax的状态
            /**
             * readyState属性表示ajax的使用状态
             * 0 表示刚创建ajax对象,还没有创建http网络请求
             * 1 表示ajax对象已经创建http网络请求,但是还没有发送请求
             * 2 表示ajax已经发送了http请求,但是服务端还没有接收到请求
             * 3 表示服务端已经接收到客户端的http请求,但是没有处理完成
             * 4 表示服务端已经处理完成客户端的http请求,并把处理结果返回给客户端了
             */
            // 5. 判断xhr执行状态已经执行完成,并且http响应状态码是200才获取服务端的数据
            if(xhr.readyState === 4){
                if(xhr.status === 200){
                    // console.log(xhr.response)     // 获取原生的响应数据[例如图片,音频等]
                    // console.log(xhr.responseText) // 获取纯文本格式数据
                    // console.log(xhr.responseXML)  // 获取xml格式的数据
                    let response = JSON.parse(xhr.response)
                    console.log(response)
                    data.style.display = "block"
                    data.innerHTML = old_conent
                    console.log(response.data.forecast)
                    for (let info of response.data.forecast) {
                         data.innerHTML+=`<tr>
                            <td>${info.date}</td>
                            <td>${info.type}</td>
                            <td>${info.fengxiang} ${info.fengli.replace(/<!\[CDATA\[(.*?)\]\]>/,"$1")}</td>
                            <td>${info.low} ~ ${info.high}</td>
                            </tr>`
                    }
                }
            }

        }
    }



</script>
</html>

方式2:使用fetch全局方法实现ajax2.0

  • 内置本质上就是XMLHttpRequest与Promise(ES6,es2015)来封装的一个函数

fetch使用文档:https://developer.mozilla.org/zh-CN/docs/Web/API/fetch

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
    .data-table{
        border-collapse: collapse;
        width: 800px;
        display: none;
    }
    .data-table td, .data-table th{
        font-weight: normal;
        border:1px solid red;
        text-align: center;
        width: 200px;
    }
    </style>
</head>
<body>
<input type="text" name="city" value="北京" placeholder="请输入一个国内的城市名称"><button>获取天气</button>
<table class="data-table">
    <tr>
        <th>日期</th>
        <th>类型</th>
        <th>风力</th>
        <th>温度</th>
    </tr>
</table>
</body>
<script>
    var btn = document.querySelector("button")
    var city = document.querySelector('input[name="city"]')
    let data = document.querySelector(".data-table")
    let old_conent = data.innerHTML // 原来的内容

    btn.addEventListener("click", get_weather)

    function get_weather(){
        // ajax2.0
        // 基于fetch全局方法来实现
        // fetch使用方式1:
        // 参数1:Request对象
        // fetch使用方式2:
        // 参数1:字符串格式的url地址,
        // 参数2:Request对象
        // 返回值:Promise回调对象
        fetch(`http://wthrcdn.etouch.cn/weather_mini?city=${city.value}`, {
            method: "GET",
            mode: 'cors',
        }).then(response => { // 此处可以简写成 then(res=>res.json())
            // 如果要接收来自服务端的json数据,则先要使用return response.json()来处理
            // 如果要接收来自服务端的纯文本数据,则先要使用return response.text()来处理
            // 如果要接收来自服务端的二进制数据,则先要使用return response.blob()来处理
            return response.json()
        })
            .then(response => {
                // 显示表格
                data.style.display = "block"
                data.innerHTML = old_conent
                for (let info of response.data.forecast) {
                    data.innerHTML += `
                    <tr>
                        <td>${info.date}</td>
                        <td>${info.type}</td>
                        <td>${info.fengxiang} ${info.fengli.replace(/<!\[CDATA\[(.*?)\]\]>/, "$1")}</td>
                        <td>${info.low} ~ ${info.high}</td>
                    </tr>
                `
                }

            }).catch((err) => {
            // 如果ajax请求失败,或者then方法中的匿名函数中有代码异常,则自动执行catch方法
            console.log("错误:", err);
            // 如果要转换处理来自服务端的异常错误
            console.log("来自服务端的错误:", err.response);
        });
    }


</script>
</html>
  • 当然,所有的ajax都可以访问别人服务端提供的数据,也可以访问自己的服务端提供的数据。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <button class="btn1">点击获取服务端的数据1</button>
    <button class="btn2">点击获取服务端的数据2</button>
    <button class="btn3">点击获取服务端的数据3</button>
    <script>
    var btn1 = document.querySelector(".btn1")
    var btn2 = document.querySelector(".btn2")
    var btn3 = document.querySelector(".btn3")
    btn1.onclick = function(){
        fetch("http://127.0.0.1:8000/",{
            method: "get",
            mode: "cors",
        }).then(response=>{
            console.log(response.text());
        })
    }

    btn2.onclick = function(){
        fetch("http://127.0.0.1:8000/",{
            method: "post",
            mode: "cors",
            headers:{
                "Content-Type": "application/json",
            },
            body: JSON.stringify({'name': 'abc'}) // 发送json数据到服务端
        }).then(response=>{
            console.log(response.text());
        })
    }

    btn3.onclick = function(){
        fetch("http://127.0.0.1:8000/xiaohong",{
            method: "put",
            mode: "cors",
        }).then(response=>{
            console.log(response.json());
        })
    }

    </script>
</body>
</html>
  • 点击按钮以后的效果: