Ajax异步

Ajax应用

前言

Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术。

  • Ajax = 异步 JavaScript 和 XML 或者是 HTML(标准通用标记语言的子集)。
  • Ajax 是一种用于创建快速动态网页的技术。
  • Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。

通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
传统的网页(不使用 Ajax)如果需要更新内容,必须重载整个网页页面。

介绍

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

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

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

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

基本使用

下面我们通过完成一个基本的功能来看一下ajax的写法:
需求:点击按钮,弹出01.txt当中的内容。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<button id="btn">点击</button>
</body>
</html>
<script>
    
window.onload = function (){


let oBtn = document.getElementById('btn');

oBtn.onclick = function() {
    var xhr =  new XMLHttpRequest();
    // 输入地址
    xhr.open('get','01.txt',true);
    // 提交
    xhr.send();
    // 等待服务器返回内容
    xhr.onreadystatechange = function(){
        if(xhr.readyState === 4){
            alert(xhr.responseText);
        }
    };
};
};
</script>

上面的代码中,我们通过ajax技术实现了点击按钮,弹出01.txt当中内容。
整体的实现步骤如下:

  • 获取元素绑定事件
  • 实例化XMLHttpRequest()对象
  • 调用open()方法读取指定文件
  • 发送请求
  • 绑定readystatechange事件,设置事件处理函数。

下面我们就来逐一的将上面的代码进行拆解讲解。

对象兼容

我们如果想在网页当中使用ajax技术,那么首先就需要创建一个XMLHttpRequest对象。这个对象目前的兼容情况是IE6以上以及其他的主流
浏览器都支持,但是如果想要在IE6及以下使用Ajax,我们就需要做一个兼容处理。

在IE6当中,需要使用ActiveXObject这个插件,并且要传入参数"Microsoft.XMLHTTP"。

示例代码:

var xhr;
if(window.XMLHttpRequest){
    xhr = new XMLHttpRequest();
 }else {
    xhr = new ActiveXObject("Microsoft.XMLHTTP");
 }

除了使用这个if和else判断以外,还可以使用try..catch的方法来实现兼容处理。

var xhr;
try{
    xhr = new XMLHttpRequest();
}catch(e) {
    xhr = new ActiveXObject("Microsoft.XMLHTTP");
}

在上面代码中,如果宿主环境中不支持XMLHttpRequest对象,就会出现错误从而会被catch所捕捉到,执行catch代码块中的另外一种声明方式。

表单当中的get方法和post方法

下面我们会说到ajaxopen方法,但是在说到这个方法之前,先来了解一下form表单当中的一些内容。

例如:

<form action="1.get.php" method="get" enctype="application/x-www-form-urlencoded">
    <input type="text" name="username">
    <input type="submit" value="提交">
</form>

在上面的表单当中,form标签存在几个属性,

  • action 表示数据提交位置 ,默认提交到当前页面
  • method 数据提交使用的方法 默认是get
  • enctype 表单数据提交的格式 默认值 application/x-www-form-urlencoded

get方法和post方法
在form表单当中,提交数据有get和post两种方法,如果从本质上来说,二者其实差异不大,但是外在的表现还是存在一定的差异。

下面就来说一下这些差异,这些差异性是w3c给出的说法:

  • GET在浏览器回退时是无害的(因为读取缓存),而POST会再次提交请求。
  • GET产生的URL地址可以被Bookmark,而POST不可以。
  • GET请求会被浏览器主动cache,而POST不会,除非手动设置。
  • GET请求只能进行url编码,而POST支持多种编码方式。
  • GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
  • GET请求在URL中传送的参数是有长度限制的,而POST么有。
  • 对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
  • GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
  • GET参数通过URL传递,POST放在Request body中。

关于get和post的区别,请关注另外一篇文章get 和 post区别介绍。

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    
    <form action="1.get.php" method="get">
        <input type="text" name="username">
        <input type="submit" value="提交">
    </form>
</body>
</html>

php代码如下:

<?php 
header("Content-type:text/html;Charset=utf-8");
// 获取用户名 
$username = $_GET['username'];
echo $username;
 ?>

在上面的案例当中,表单通过get方式向php传递了数据,在页面的地址栏位置,我们可以发现通过url地址进行提交时,
把数据名称和数据值使用=进行连接,如果是多个的话,那么会把多个数据使用&进行连接,然后把数据放到url?后面传到指定页面。

open()方法

下面我们来说一下open()方法,通过这个方法,我们可以设置发送请求的方法,地址,以及是否异步。

xhr.open(method,url,async);

例如:

xhr.open('get','01.txt',true);

当传输数据的方法为get方法的时候

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

例如:

var xhr = null;

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

xhr.send();


xhr.onreadystatechange = function(){

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

当传输数据的方法为post方法的时候

当传输数据为post方法的时候,需要传递的参数应该通过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','08.php',true);
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.send("name=zhangsan&age=14");
xhr.onreadystatechange = function(){
    if(xhr.readyState === 4 && xhr.status === 200){
        alert(xhr.responseText);
    } 
};

绑定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(获得字符串形式的响应数据。) 或 responseXML(获得 XML 形式的响应数据) 属性。

例如:

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

小练习:点击按钮读取数据

html代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>新闻列表</title>
</head>
<body>
    <button id="btn">点击</button>
    <ul id="list">
        
    </ul>
</body>
<script>
    window.onload = function(){

        // 获取list
        var oList = document.getElementById('list');
        var oBtn = document.getElementById('btn');

        oBtn.onclick = function(){

            var xhr = null;

            if(window.XMLHttpRequest){
                xhr = new XMLHttpRequest();
            }else {
                xhr = new ActiveXObject("Microsoft.XMLHTTP");
            }


            xhr.open('get','06.get.php',true);
            xhr.send();


            xhr.onreadystatechange = function() {

                if(xhr.readyState === 4 && xhr.status === 200){

                    // 拿到数据进行处理
                    console.log(xhr.responseText);
                    var news = JSON.parse(xhr.responseText);
                    console.log(news);// 数组
                    var html = '';
                    for(let i=0;i<news.length;i++){

                        // 将数据插入到li 并且存储到html
                        html += `<li><a href="">${news[i].title}</a> [<span>${news[i].date}</span>]</li>`;

                    }
                    oList.innerHTML = html;
                }
            };
        };
    };
</script>
</html>

php代码:

<?php
header("Content-type:text/html;Charset=utf-8");
$arr_news = [
    ['title'=>'美国从不愿提及的真相:中朝战俘境遇','date'=>'2019-05-27'],
    ['title'=>'县级领导网上筹款20万治病 家人及官方回应','date'=>'2019-05-26'],
    ['title'=>'杜特尔特“拷问”女副总统为啥不笑 13分钟后见效','date'=>'2019-05-25'],
    ['title'=>'翟天临又上热搜了 是被半夜改论文毕业生骂上去的','date'=>'2019-05-24'],
    ['title'=>'美国百岁老人被房东驱逐 惊动了“硬汉”施瓦辛格','date'=>'2019-05-23'],
    ['title'=>'实习女律师当街遇害 知情者:行凶男子想杀漂亮女孩','date'=>'2019-05-22'],
    ['title'=>'国内成品油价格迎来年内第八涨 加满一箱油多花2元','date'=>'2019-05-21'],
    ['title'=>'中安民生“以房养老”骗局:老人被逼卖房还高利贷','date'=>'2019-05-20'],
    ['title'=>'任正非:华为必须做世界第一 若第二可能活不下来','date'=>'2019-05-19'],
    ['title'=>'91岁李兆基退休:香港富豪“四大天王”时代落幕','date'=>'2019-05-18']
];

echo json_encode($arr_news);

上面的代码中,我们点击按钮就可以在页面中显示php给我们返回的数据。

ajax函数封装

为了便于操作,我们也可以将ajax常用的操作进行封装。

function ajax(method, url, data, success) {
    var xhr = null;
    try {
        xhr = new XMLHttpRequest();
    } catch (e) {
        xhr = new ActiveXObject('Microsoft.XMLHTTP');
    }
    
    if (method == 'get' && data) {
        url += '?' + data;
    }
    
    xhr.open(method,url,true);
    if (method == 'get') {
        xhr.send();
    } else {
        xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
        xhr.send(data);
    }
    
    xhr.onreadystatechange = function() {
        
        if ( xhr.readyState == 4 ) {
            if ( xhr.status == 200 ) {
                success && success(xhr.responseText);
            } else {
                alert('出错了,Err:' + xhr.status);
            }
        }
        
    }
}

有了这个函数,上面的小练习就可以写成下面的样式:

ajax('get','06.get.php','',function(data) {
    var data = JSON.parse( data );
        
    var oUl = document.getElementById('ul1');
    var html = '';
    for (var i=0; i<data.length; i++) {
        html += '<li><a href="">'+data[i].title+'</a> [<span>'+data[i].date+'</span>]</li>';
    }
    oUl.innerHTML = html;
});

我们也可以通过轮询的形式让前端新闻自动请求后端的数据:

setInterval(function() {
    ajax('get','getNews.php','',function(data) {
        var data = JSON.parse( data );
            
        var oUl = document.getElementById('ul1');
        var html = '';
        for (var i=0; i<data.length; i++) {
            html += '<li><a href="">'+data[i].title+'</a> [<span>'+data[i].date+'</span>]</li>';
        }
        oUl.innerHTML = html;
    });
}, 3000);

小练习

下面通过ajax + 多列布局来实现瀑布流效果:

html代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        *{
            margin:0;
            padding:0;
            box-sizing: border-box;
        }
        body{
            background:#352323 url(images/a.png);
        }
        img{
            display:block;
        }
        section{
            max-width:95%;
            margin:0 auto;
            overflow:hidden;
            column-count: 5;    
            column-gap:0;
            column-fill: auto;
        }
        figure{
            border:2px solid pink;
            margin:0 5px 10px;
            break-inside: avoid;    
            padding:5px;
        }
        figure img{
            width:100%;
        }
        figcaption{
            padding:10px 0;
            text-align:center;
            font-weight:900;
            color:#a77869;
        }
    </style>
</head>
<body>
    <section>
        <!-- <figure>
            <img src="images/1.jpg" alt="">
            <figcaption>往后余生,风雪是你</figcaption>
        </figure> -->
    </section>
</body>
<script src="ajax.js"></script>
<script>
    let section = document.getElementsByTagName('section')[0];
    ajax('get','img.php','num=100',function(data){
        let img_data = JSON.parse(data);
        console.log(img_data)
        for(let i=0;i<img_data.length;i++){
            
            // 创建figure标签
            let figure = document.createElement('figure');

            // 创建里面的两个子元素
            let img = document.createElement('img');
            img.src = img_data[i];

            let figcaption = document.createElement('figcaption');

            figcaption.innerHTML = "往后余生,风雪是你";

            figure.appendChild(img);
            figure.appendChild(figcaption);
            section.appendChild(figure)
        }
    })
</script>
</html>

php代码如下:

<?php
header("Content-type:text/html;Charset=utf-8");


$num = $_GET['num'];// 通过get方式传递数据  
$img = file("img.txt"); // 读取文件地址

$arr_url = array();
for($i=0;$i<$num;$i++){
    $url = array_rand($img);
    array_push($arr_url,$img[$url]);
}

// 返回json数据 
$a = json_encode($arr_url,JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE);
echo $a;

在上面的代码中,我们只需要每次在请求的时候设置好num参数即可以得到图片。

转载于:https://www.cnblogs.com/liujunhang/p/10940995.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值