Ajax

Ajax介绍

前言

在学习Ajax之前,我们先来聊一下同步和异步的问题。

什么是同步?什么是异步呢?

首先来说同步,同步相对来说更好理解一点。比如调用一个方法,这个方法没有调用完成之前,后续的代码将不能够执行。这就是同步。
那么什么是异步呢,异步调用有些类似于消息传递,一旦开始,方法调用就会立刻返回,调用者就可以继续后面的操作。需要知道的是,此时,异步方法通常会在另外一个
线程中真实的执行着。整个过程当中,并不会阻碍调用者的工作。

而Ajax主要的工作就是通过异步来帮助我们传输数据。

介绍

Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术。使用Ajax,我们可以无刷新状态更新页面,并且实现异步提交,提升了用户体验。

  1. JavaScript,通过用户或其他与浏览器相关事件捕获交互行为
  2. XMLHttpRequest 对象,通过这个对象可以在不中断其它浏览器任务的情况下向服务器发送请求;
  3. 服务器上的文件,以 XML、HTML 或 JSON 格式保存文本数据;
  4. 其它 JavaScript,解释来自服务器的数据(比如 PHP 从 MySQL 获取的数据)并将其呈现到页面上。

由于 Ajax 包含众多特性,优势与不足也非常明显。优势主要以下几点:

  1. 不需要插件支持(一般浏览器且默认开启 JavaScript 即可);
  2. 用户体验极佳(不刷新页面即可获取可更新的数据);
  3. 提升 Web 程序的性能(在传递数据方面做到按需发送,不必整体提交);
  4. 减轻服务器和带宽的负担(将服务器的一些操作转移到客户端);

而 Ajax 的不足由以下几点:

  1. 不同版本的浏览器对 XMLHttpRequest 对象支持度不足(比如 IE5 之前);
  2. 前进、后退的功能被破坏(因为 Ajax 永远在当前页,不会记录前后页面);
  3. 搜索引擎的支持度不够(因为搜索引擎爬虫还不能理解 JS 引起变化数据的内容);

Ajax应用

基本使用

1.创建请求对象;

  var AJAX=new XMLHttpRequest( );

2.设置请求参数;

  AJAX.open('get','data/test.json',true);

3.观察状态(是否接通)

AJAX.onreadystatechange = function(){
       if (AJAX.readyState == 4 && AJAX.status == 200){
           func_succ(AJAX.responseText);
       }else if(AJAX.readyState == 4 && AJAX.status != 200){
           //alert("AJAXfaild readyState:"+AJAX.readyState+" status:"+AJAX.status);
       }
   };

4.提交

 AJAX.send();

对象兼容

ajax = new XMLHttpRequest();
ajax = new ActiveXObject("Microsoft.XMLHTTP");     //IE5

open()方法

通过open方法,我们可以设置发送请求的方法,地址,以及是否异步。

xhr.open(method,url,true);

第一个参数:POST||GET
POST和GET的区别:
1.POST主要用来发送数据,GET主要用来接受数据;
2.PSOT发送数据的安全性较好,而GET较差;
3.POST发送数据不限制大小,而GET大小受限2~100k。
什么时候用GET和POST:在数据获取时用GET方式,在操作数据时应使用POST方式。
第二个参数:要请求的url
第三个参数:接受一个布尔值,决定请求的方式
为true时,服务器请求是异步进行的,也就是脚本执行send() 方法后不等待服务器的执行结果,而是继续执行脚本代码;
为false时,服务器请求是同步进行的,也就是脚本执行send() 方法后等待服务器的执行结果的返回,若在等待过程中超时,则不再等待,继续执行后面的脚本代码!

当传输数据的方法为get方法的时候
传输数据的时候,如果是get方法,那么在url地址中可能存在参数,参数是以?和& 进行拼接。

var xhr = null;

if(window.XMLHttpRequest){
    xhr = new XMLHttpRequest();
}else {
    xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
// 将参数通过?的形式进行拼接 
xhr.open('get','test.php?name=zhangsan&age=18',true);

xhr.onreadystatechange = function(){
    if(xhr.readyState === 4 && xhr.status === 200){
        alert(xhr.responseText);
    } 
};
xhr.send();

当传输数据的方法为post方法的时候
当传输数据为post方法的时候,数据不在url身上。需要传递的参数应该通过send()方法进行传递。同时需要设置一下数据传输格式。

如下:

// 设置发送数据的格式为表单数据
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");

例如将上面的案例转换成post方法,代码如下:

var xhr = null;
if(window.XMLHttpRequest){
    xhr = new XMLHttpRequest();
}else {
    xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
xhr.open('post','test.php',true);
xhr.onreadystatechange = function(){
    if(xhr.readyState === 4 && xhr.status === 200){
        alert(xhr.responseText);
    } 
};
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.send("name=zhangsan&age=18");

绑定onreadystatechange事件

上面我们将数据发送到了服务器,服务器接收到后会进行一定的处理,而onreadystatechange事件监听的就是XMLHttpRequest对象的readyState的状态。
一旦状态发生改变都会触发这个事件。

xhr.onreadystatechange = function(){};

readyState和status

readyState里面存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。

0: 请求未初始化
1: 服务器连接已建立
2: 请求已接收
3: 请求处理中
4: 请求已完成,且响应已就绪
status里面存储的是http状态码,根据不同的情况,服务器会返回不同的状态码。200表示成功。
一般情况下,我们都是等readyState的值变为4,status的值为200的时候才去处理返回的数据。

xhr.onreadystatechange = function () {
    if(xhr.readyState === 4 && xhr.status === 200){
        // code ...
    }
}

获取服务器响应

当我们通过XMLHttpRequest对象向服务器发起请求之后,服务器会给予我们一定的响应,那么我们该如何获取响应呢?
可以通过XMLHttpRequest 对象的 responseText属性。

xhr.onreadystatechange = function () {
    if(xhr.readyState === 4 && xhr.status === 200){
        alert(xhr.responseText);
    }
}

ajax缓存问题:用时间戳清除缓存

ajaxGet('data/test.txt?t='+ new Date().getTime(),fn)

Ajax封装

function ajax(options){
    // 1.处理默认参数
    var {type,url,success,error,data,timeout} = options;
    type = type || "get";
    data = data || {};
    timeout = timeout || 2000;

    // 2.解析要发送的数据
    var str = "";
    for(var i in data){
        str += `${i}=${data[i]}&`;
    }

    // 3.根据方式,决定是否处理url
    if(type == "get"){
        var d = new Date();
        url = url + "?" + str + "__qft=" + d.getTime();
    }

    // 4.开启ajax
    var xhr = new XMLHttpRequest();
    // 注意:open中的方式
    xhr.open(type,url,true);
    xhr.onreadystatechange = function(){
        if(xhr.readyState == 4 && xhr.status == 200){
            // 5.执行成功之前,先判断是否传入
            success && success(xhr.responseText);
            // 成功之后,不应有失败
            error = null;
        }else if(xhr.readyState == 4 && xhr.status != 200){
            // 6.执行失败之前,先判断是否传入
            error && error(xhr.status);
            // 失败之后,不应有成功
            success = null;
            // 且失败不应多次执行
            error = null;
        }
    }

    // 7.如果请求超时,执行失败
    setTimeout(() => {
        error && error("timeout");
        // 失败之后,不应有成功
        success = null;
    }, timeout);

    // 8.最后根据type的方式,决定send的发送内容和格式
    if(type == "post"){
        xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
        xhr.send(str)
    }else{
        xhr.send()
    }
    }

上述封装完成之后,拿来使用时传参就可以了

  ajax({
            type:"get",                 //发送方式,可选,默认get
            url:"http://localhost/ajax/data/data.php",   //要请求的地址,必选
            success:function(res){         //请求成功之后的函数,必选
                console.log(res)
            },
            data:{                      //要发送的数据,可选,默认不发
                user:"admin",
                pass:123456789
            },
            error:function(res){         //请求失败之后的函数,可选,默认不处理
                console.log(res)
            },
            timeout:10                  //请求超时的时间,可选,默认2000
        })

Ajax实现商品列表

服务器的交互以及JSON的格式。
eval( )方法:将字符串转换成JavaScript可以认识的编码;

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>商品列表</title>
    <style>
    *{
        margin: 0;
        padding: 0;
    }
    #box{
        width: 1200px;
        overflow: auto;
        margin: 200px auto;
        border:1px solid pink;
    }
    #box div{
        width: 300px;
        height: 300px;
        box-sizing: border-box;
        border:1px solid red;
        text-align: center;
        overflow: hidden;
        float:left;
    }
    #box div h3{
        color: red;
        font-size: 20px;
        line-height: 40px;
        padding-top: 20px;
    }
    #box div img{
        width: 160px;
        height: 160px;
    }
    #box div span{
        font-size: 18px;
        color: #ccc;
        padding-top: 10px;
    }
    </style>
</head>
<body>
    <div id="box"></div>
</body>
<script src="../ajax.js"></script>
<script>

    class List{
        constructor(){
            this.url = "http://localhost/ajax/data/test.json";
            this.box =document.getElementById("box");

            this.load();
        }
        load(){
            ajax({
                url:this.url,
                success:res=>{
                    this.res = JSON.parse(res);
                    this.display()
                }
            })
        }
        display(){
            var str ="";
            for(var i=0;i<this.res.length;i++){
                str+=`<div>
                    <img src="${this.res[i].url}" alt="">
                    <h3>${this.res[i].name}</h3>
                    <span>${this.res[i].price}</span>
                    </div>`
            }
            this.box.innerHTML=str;
        }
    }
    
    new List();
</script>
</html>

json如下:

[
    {
        "name":"Redmi Note 8 Pro",
        "price":"1399元起",
        "url":"images/1.jpg"
    },
    {
        "name":"Redmi Note 8",
        "price":"999元起",
        "url":"images/2.jpg"
    },
    {
        "name":"Redmi K20 Pro 6GB+128GB",
        "price":"2299元",
        "url":"images/3.jpg"
    },
    {
        "name":"Redmi Note 7",
        "price":"1099元",
        "url":"images/4.jpg"
    },
    {
        "name":"Redmi 7 ",
        "price":"699元起",
        "url":"images/5.jpg"
    },
    {
        "name":"小米MIX 3 8GB+128GB",
        "price":"2599元",
        "url":"images/6.jpg"
    },
    {
        "name":"小米CC9",
        "price":"1799元起",
        "url":"images/7.jpg"
    },
    {
        "name":"小米9 SE",
        "price":"1599元起",
        "url":"images/8.jpg"
    }
]

最终效果如下:
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值