Ajax学习笔记

JSON Ajax – 掌握

1.JSON

1.1概念
    数据格式,实质是一个字符串
1.2注意
    1)属性名必须使用双引号
    2)当属性值是字符串形式时,必须使用双引号
    3)JSON文件中不允许出现注释
    4)JSON数据不支持undefined和函数,对比js对象 则可以
1.3例子
{
            "title":"苹果手机",
            "list":[
                {
                    "id":1,
                    "name":"苹果13",
                    "price":"5799元"
                },
                {
                    "id":2,
                    "name":"苹果13 pro",
                    "price":"7799元"
                },
            ]
        }

1.4方法
1)JSON.parse(JSON的字符串) -- 将JSON数据格式转换为js对象 (串-->对象) 常用
2)JSON.stringify(object) -- 将js对象转换为JSON字符串 
1.5 举例实现
<script>
        //创建js对象
        let obj = {
            name: '李通',
            age: 20,
            marry: false,
            girlFriend: undefined,
            height: null,
            hobby: ['唱', '跳', '篮球'],
            friend: {
                name: '海龙',
                age: 19
            },
            job() {
                console.log('一名小学生');
            }
        }
        console.log(obj, typeof obj);
        //js对象转换为JSON字符串
        let str = JSON.stringify(obj);
        console.log(str, typeof str);//{"name":"李通","age":20,"merry":false,"height":null,"hobby":["唱","跳","篮球"],"friend":{"name":"海龙","age":19}}  string

        let myJson='{"name":"李通","age":20,"merry":false,"height":null,"hobby":["唱","跳","篮球"],"friend":{"name":"海龙","age":19}}';
        //JSON字符串转换为js对象
        console.log(JSON.parse(myJson));
        console.log(typeof JSON.parse(myJson));
    </script>

2.ajax

2.1概念
    异步的js和xml
2.2作用
    客户端给服务端发送http请求 
2.3特点(重点)
    1)异步请求
        同步请求--第一个请求没有完成,第二个请求不可以发送
        异步请求--第一个请求没有完成,不影响后面的请求
    2)局部刷新
        form发送请求--刷新整个页面(不推荐)
        ajax发送请求--局部刷新--登录、注册页面,快递单号查询、搜索等
2.4优点
    局部刷新-->给客户端节省宽高,提高用户的体验度
2.5缺点
    依赖于js,浏览器不支持js,ajax就无法运行,ajax应用程序中安全性较低
2.6原理
  • 在前端请求和服务器 中间的中间商

      1)前端创建ajax对象
      2)让ajax对象去请求服务器
      3)服务器接收到前端的请求,处理请求
      4)服务器把处理的数据返回给ajax对象
      5)客户端渲染Ajax对象拿到的数据
    
2.7Ajax请求步骤
  1. 创建xhr对象 – 秘书

let xhr = new XMLHttpRequest();
xhr 返回值对象,js实现获取对象的属性,.

  1. 准备发送请求 – 让秘书找小王
    xhr.open('请求方式','url',true);

    • 请求方式 post/get
    • url 后台地址
    • 第三个属性:是否同步与异步 ajax必须true
  2. 发送请求 – 秘书去找小王
    xhr.send();

  3. 监听函数 – 监督秘书的工作
    onreadystatechange

    • 检查请求的发送与失败
  4. 状态执行完毕获取数据 – 秘书成功找到小王

xhr.onreadystatechange=function(){
        //后台成功的响应正确的数据
        if(xhr.readyState===4 && status === 200){
            //成功获取后台的数据
            xhr.response //返回后台的数据
        }
    }
2.8http协议状态码
    200 -- 成功
    404 -- 资源不存在
    5XX -- 后台的错误
2.9Ajax对象和服务器交互时产生的状态值
    0 -- 还没有发送请求
    1 -- 开始发送请求
    2 -- 服务器接收到请求
    3 -- 服务器处理请求
    4 -- 服务器响应请求
2.10 使用AJAX与传统web的区别
  • 之前的页面请求都是form 表单post与get的形式,整个页面刷新,用户体验差
  • jajx 请求,利用XMLHttpRequest 创建对象,对象访问服务器,局部刷新即可实现,同时,服务器处理后的信息,首先返回到对象,对象给客户端,然后js 渲染到页面
2.11 举例实现
    <script>
        //ajax使用步骤
        //1.创建xhr对象 -- 秘书
        let xhr = new XMLHttpRequest();
        console.log(xhr);

        //2.准备发送请求 -- 让秘书找一下小王
        xhr.open('get', './06ajax.php', true);

        //3.发送请求 -- 秘书去找小王
        xhr.send();

        //4.监听函数 -- 监督秘书的工作
        //只要状态发生改变,就会触发事件,事件会触发多次
        xhr.onreadystatechange = function () {
            //5.状态执行完毕才可以获取数据 -- 秘书正确的找到了小王
            if (xhr.readyState === 4 && xhr.status === 200){
                //成功获取后台的数据
                console.log(xhr.response);
            }
        }
    </script>

3.Ajax传递参数

3.1get传递参数

1)语法
后边的数据太长,可以使用一个变量传递

xhr.open('get','url?后台参数=前端参数值&后台参数=前端参数值',true);

//get传参在地址栏中
            //url?后台参数=前端参数值&后台参数=前端参数值
            // 后台参数: $_POST或者$_GET中括号里边的参数 
            // 前端参数值 用户数输入的参数值 ,变量 模板字符串的拼接处理
            let params = `username=${user}&password=${pwd}`;
		  // 模板字符串注意空格问题	
            xhr.open('get', './php/03get.php?' + params, true);

2)说明
get传递参数是在url地址栏中传参,所以直接操作地址栏

<body>
    <div class="box">
        <p>
            <input type="text" placeholder="输入用户名" class="name">
        </p>
        <p>
            <input type="text" placeholder="输入密码" class="pwd">
        </p>
        <p>
            <input type="button" value="登录" class="btn">
        </p>
    </div>

    <script>
        // 点击button,利用ajax 提交数据到后台,并返回给前端
        document.querySelector('.btn').onclick = function(){
            // 开始aja请求
            let user = document.querySelector('.name').value
            let pwd = document.querySelector('.pwd').value
            // 1. 创建对象

            let xhr = new XMLHttpRequest()
            // console.log(xhr);
            

            // 2.打开
            // 后台数据=前端数据& 后台数据=前端数据
            let str = `user= ${user} & password = ${pwd} `
            xhr.open('get','./php/ex-03get.php?'+str,true)

            // 3.发送
            xhr.send()

            // 4.处理ajax数据
            xhr.onreadystatechange = function(){
                if(xhr.readyState === 4 && xhr.status===200){
                    console.log(xhr.response);
                }
            }
        }
       
    </script>
</body>
3.2post传递参数
  1. 语法
    xhr.open('post','url',true);

  2. //设置请求头
    请求头的位置位于必须位于open send 之间

 xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded;charset=utf-8");
    
    xhr.send('后台参数=前端参数值&后台参数=前端参数值');

 <script>
        document.querySelector('.btn').onclick = function(){
            let user = document.querySelector('.user').value;
            let pwd = document.querySelector('.pwd').value;
            
            // console.log(user,pwd);
            
            // ajax 处理过程

            let xhr = new XMLHttpRequest()

            xhr.open('post','./php/ex-4post.php',true)


            // post 设置请求头
            xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded;charset=utf-8");

            // post传递的参数

            xhr.send(`username=${user}&password=${pwd}`)

            // xhr.send(`username=${user}&password=${pwd}`);

            xhr.onreadystatechange = function(){
                if(xhr.readyState ===4 && xhr.status ===200){
                    console.log(xhr.response);
                    // console.log(xhr);
                }
            }


        }
    </script>
3.3 案例-快递单号查询
  • 技术难点
    1. 单独抽离出来 时间函数,对时间的处理,参数传递,返回值

    2. 前后端数据处理,检测到数据后,数据渲染到页面

         <h2>查找快递案例实现</h2>
         <h3>快递单号:4307101743736</h3>
         快递单号:<input type="text" class="num">
         <input type="button" value="查询" class="btn">
         <ul>
     
         </ul>
<script>
        // 分析
        // 输入单号 点击查询 xhr请求到后端  查看是否有数据 
        // 没有数据 返回"没有单号信息
        // 有数据: 将处理处理后渲染到 ul中
        // 单独抽离出来事件函数

        // 1点击开始查询
        document.querySelector('.btn').onclick = function () {
            // 获取用户输入的表单
            let num = document.querySelector('.num').value
            let ul = document.querySelector('ul')

            // 判断用户是否输入数据
            if (num === '') {
                // 用户没有输入数据
                alert('输入快递单号后,开始查询')
            } else {
                // 用户输入了数据

                // 2 xhr 

                let xhr = new XMLHttpRequest()

                xhr.open('post', './php/ex-05kuaidi.php', true)

                xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded;charset=utf-8")
                xhr.send(`num=${num}`)

                xhr.onreadystatechange = function () {

                    if (xhr.readyState === 4 && xhr.status === 200) {
                        // 判断是否存在数据
                        if (xhr.response == 0) {
                            // 不存在物流信息
                            ul.innerHTML = `
                            <h4>物流追踪</h4>
                            <p>暂未查到与您单号相关的物流信息,请稍后再尝试。<p>
                            `
                        } else {

                            // 3 存在物流信息,开始处理信息
                            //    将json数据转为js 对象 找到对应的数据数组 循环数组 渲染到页面
                            let obj = JSON.parse(xhr.response)
                            // console.log(obj);
                            let arrData = obj.data.info.context
                            console.log(arrData);

                            let str = ''
                            for (let i = 0; i < arrData.length; i++) {
                                str += `
                                        <li>
                                            <h5>物流时间:${time(arrData[i].time)}</h5>
                                            <p>物流信息:${arrData[i].desc}</p>
                                        </li>
                                     `
                            }
                            ul.innerHTML = str

                        }
                    }
                }


                // 对返回的数据单位处理
                function time(date) {
                    // 对事件的处理,毫秒,返回数据,miao
                    let time = new Date(date * 1000)

                    let year = time.getFullYear()
                    let month = time.getMonth()
                    let day = time.getDate()
                    let hours = time.getHours()
                    let secondes = time.getMinutes()
                    let minus = time.getMinutes()

                    // 事件补零操作
                    secondes = secondes > 10 ? secondes : '0' + secondes
                    minus = minus > 10 ? minus : '0' + minus


                    return `${year}${month}${day}${hours}${secondes}${minus}`


                }
            }



        }

    </script>
    <?php
    $num = $_POST['num'];

    $data ='这里是后台给过来的数据';
    if($num =='4307101743736'){
        // 存在对应的单号,将数据返回给前端,前端处理数据
        echo $data;
    }
    else{
        // 不存在快递数据,返回0
        echo 0;
    
    }

4.jquery封装的Ajax

4.1语法
$.ajax({
            type:'get|post',//请求方式 (必须属性)
            url:'路径',//请求的地址 (必须属性)
            data:{//传参 -- 没有参数可以省略,es6新语法,如果两个参数名一样,可以省略一个
                后台参数:前端参数值,
                后台参数:前端参数值,
                后台参数:前端参数值,
            },
            dataType:'返回的数据类型',//可以省略
            async:'是否异步',//默认true--异步--可以省略
            success:function(res){//形参--用来接收后台成功时返回的数据

            },
            error:function(err){//形参--用来接收后台失败时返回的数据--可以省略

            },
            beforeSend:function(){//请求成功之前执行的函数--可以省略

            },
            complete:function(){//请求完成时执行的函数,不管成功还是失败--可以省略

            }

        });

5.自己封装Ajax

5.1参考jquery封装的ajax
    jquery中的ajax:
        $.ajax({
            type:'',
            url:'',
            data:{},
            success(res){}
        })
5.2 封装原生ajax:
    myAjax({
        type:'',
        url:'',
        data:{},
        success(res){}
    });
5.3原生ajax:
    1.创建xhr对象
    let xhr=new XMLHttpRequest();
    2.准备发送请求
    xhr.open('method','url',true);
    3.发送
    xhr.send();
    4.监听
    xhr.onreadystatechange=function(){
        //5.状态完成
        if(xhr.readyState===4&&xhr.status===200){
            xhr.response//获取后台返回的数据
        }
    }
5.4 封装

1)点击按钮,发送http请求
2)判断get请求还是post请求
2)get请求在open中传参,post请求在send中传参
技术难点

  • 处理参数字符串 循环遍历data对象,遍历之后对串的拼接
  • 拼接字符串注意空格问题
  • str += ${key}=${obj.data[key]}& user=DD& password=21&
  <script>
        // 分析
        // 点击button,发送请求
        // 参考jquery封装的Ajax

        // 自己封装Ajax,原生js实现
        document.querySelector('#btn').onclick = function () {
            let user = document.querySelector('#user').value
            let pwd = document.querySelector('#pwd').value

            // 调用函数 myAjax() 实参传递的参数是一个对象 调用对象的属性和方法,形参obj.属性方法
            myAjax({
                type: 'get',
                url: './php/ex-03get.php',
                data: {
                    user: user,
                    password: pwd
                },
                success: function (res) {
                    console.log(res);
                }
            })
        }


        // 封装函数
        function myAjax(obj) {
            // 原生js实现ajax封装
            // console.log(obj);

            // 1.创建对象
            let xhr = new XMLHttpRequest()


            // 3.处理字符串参数字符串
            // console.log(obj.data); //获取前后台参数,返回对象
            let str = ''
            for (const key in obj.data) {
                // console.log(key);  //输出对象的属性 user passwprd
                // console.log(obj.data[key]); // 输出兑现的属性值 (用户输入的部分)
                // 后台属性 = 前台属性值 
                str += `${key}=${obj.data[key]}&`
            }
            // 去掉最后一个&
            let params = str.slice(0, -1)

            // console.log(str);  user=DD&password=21&
            // console.log(params);  //user=DD&password=21


            // 2.判断请求的类型
            if (obj.type === 'get') {
                xhr.open('get', obj.url + '?' + params, true)
                xhr.send()
            } else if (obj.type === 'post') {
                xhr.open('post', obj.url, true)
                xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
                xhr.send(params)
            }


            // 4.时间监听
            xhr.onreadystatechange = function () {
                if (xhr.readyState === 4 && xhr.status === 200) {
                    // 给调用函数的返回值,函数的获取,对象 . 
                    obj.success(xhr.response);
                }
            }
        }


    </script>

6跨域

6.1 理解跨域
  1. 当前域名下网站去访问其他域名下的网站,浏览器出于安全考虑的同源策略

  2. 同源:协议,域名,端口号 只有这三个全部相同,才能实现访问

  3. 跨域:协议,域名,端口号 不同时,不能访问,解决办法,跨域处理

6.2 解决跨域问题

不同域名之间的访问,大型项目的前端和后台的数据可能不在一个服务器上

  • jsonp —对数据的格式有问题
  • cors 资源共享 —后台配置
  • proxy 反向代理 —框架
  • 后台代理(php代理)
6.2.1 后台代理 解决跨域
  1. 思路
    php 访问服务器,服务器将数据返回给php,php将数据响应给前端
  2. 语法
    php访问服务器
    file_get_contents(‘服务器路径’)
  3. 直接访问出现的bug
    has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
6.2.2 jsonp 解决跨域
  1. 原理:
    • 动态创建script标签 (创建之后得添加到页面)
    • 设置src属性去访问资源(src 属性可以往上访问所有的资源,不会产生跨域问题)
    • 后台给前端响应数据,前端定义函数 去接受返回的数据
  2. 补充
    • 只支持get请求
    • 返回的数据必须是一个函数
  3. 实现过程
<body>
    <input type="text" id="text">
    <button id="search">百度一下</button>
    <script>
        //jsonp解决跨域
        //1.创建script  2.scr请求数据  3.前端用函数接收返回的数据

        //1.绑定点击事件
        document.getElementById('search').onclick = function () {
            //2、获取当前值
            let text = document.getElementById('text').value;

            //3.网络请求
            //3.1创建script
            let script = document.createElement('script');
            //3.2scr请求数据
            //wd -- 后台定义接收前端参数的变量
            //cb=callback -- cb:后台定义用来接收前端函数的变量,callback:前端接收数据的变量名
            script.src = 'http://suggestion.baidu.com/su?cb=callback&wd=' + text;
            //3.3添加到body中
            document.body.appendChild(script);

        }

        //3.4前端定义接收数据的函数
        function callback(res){
            console.log(res);
        }

    </script>
</body>
6.2.3 jQuery 封装的jsonp 解决跨域问题
<body>
    <input type="text" id="text">
    <button id="search">百度一下</button>

    <script src="./js/jquery-3.6.0.min.js"></script>
    <script>
        //1.绑定点击事件
        $('#search').click(function () {
            //2.获取当前值
            let text = $('#text').val();

            //3.网络请求
            //使用jquery封装的jsonp解决跨域
            $.ajax({
                type: 'get',
                url: 'http://suggestion.baidu.com/su?',
                data: {
                    //后台参数:前端参数值
                    wd: text
                },
                dataType: 'jsonp',//返回的数据格式必须设置
                jsonp: 'cb',//后台定义用来接收前端函数的变量名,默认为callback,如果是callback可以省略
                // jsonpCallback:'callback',//前端接收数据的函数名--一直可以省略,省略后默认为:jquery+随机数字
                success(res) {
                    console.log(res);
                }
            })

        })
    </script>
</body>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值