最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Ajax(上)

    正文概述 掘金(前端小白1995)   2020-11-29   733

    什么是Ajax

    Ajax 的全称是 Asynchronous JavaScript and XML(异步的 JavaScript 和 XML),是一种用于创建动态网页(与后端交互)的技术。

    Ajax 技术指的是脚本独立向服务器请求数据,拿到数据以后,进行处理并更新网页。整个过程中,后端只是负责提供数据,其他事情都由前端处理,实现了 获取数据 → 处理数据 → 展示数据 的完整业务逻辑。

    同步与异步

    同步

    所有的操作都做完,才返回给用户。这样用户在线等待的时间太长,给用户一种卡死了的感觉(就是系统迁移中,点击了迁移,界面就不动了,但是程序还在执行,卡死了的感觉)。这种情况下,用户不能关闭界面,如果关闭了,即迁移程序就中断了。

    异步

    将用户请求放入消息队列,并反馈给用户,系统迁移程序已经启动,你可以关闭浏览器了。然后程序再慢慢地去写入数据库去。这就是异步。但是用户没有卡死的感觉,会告诉你,你的请求系统已经响应了。你可以关闭界面了。

    工作原理

    在客户端(如浏览器)和服务器之间加了一个中间层:Ajax 引擎。由 Ajax 引擎独立向服务器请求数据,前端获取到 Ajax 返回的数据后,可以使用新数据来更新页面、或进行其它操作,使用户请求和服务器响应异步化,从而保证了在不刷新页面的前提下可以局部更新网页内容。

    Ajax(上)

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Ajax</title>
    </head>
    <body>
        <div id="view">
            <p>点击下面的按钮,将 Ajax 请求回来的数据更新在该文本内</p>
        </div>
        <button type="button" id="btn">发起 Ajax 请求</button>
    
        <script>
            document.getElementById("btn").onclick = ajaxRequest;
            function ajaxRequest () {
                //实例化一个XMLHttpRequest对象
                var xhr = new XMLHttpRequest();
                //open()规定请求的类型、url、是否异步
                xhr.open("GET","https://www.w3cschool.cn/statics/demosource/ajax_info.txt", true);
                xhr.send();
    		   //send()发送请求,必须结合open一起使用
                xhr.onreadystatechange = function(){
                    //监测服务器响应的状态
                    if (xhr.readyState === 4 && xhr.status === 200) {
                        //当 readyState 等于 4 且状态为 200 时,表示成功响应
                        document.getElementById("view").innerHTML = xhr.responseText;
                    }                
                }
            }
        </script>
    </body>
    

    优点与缺点

    优点:

    1. 页面无刷新更新,用户的体验非常好;
    2. 异步通信,响应更快
    3. 可以将一些服务器工作转移到客户端,利用客户端资源来处理,减轻服务器和带宽的压力,节约空间和带宽租用成本;
    4. 技术标准化,并被浏览器广泛支持,不需要下载插件或者小程序;
    5. Ajax 可使因特网应用程序更小、更快、更友好。

    缺点:

    1. Ajax 不支持浏览器 back 返回按钮;
    2. 有安全问题,Ajax 暴露了与服务器交互的细节;
    3. 对搜索引擎不友好;
    4. 破坏了程序的异常机制;
    5. 不容易调试。

    同源策略

    url的组成

    一个 URL 地址可以有以下几个组成部分:scheme: //host:post/path?query#fragment

    • scheme:通信协议,一般为 http 、https;
    • host:域名;
    • post:端口号,此项为可选项,http 协议默认的端口号为 80,https 协议默认的端口号为 443;
    • path:路径,由 "/ "隔开的字符串;
    • query:查询参数,此项为可选项;
    • fragment:信息片段,用于指定网络资源中的某片断,此项为可选项;

    网址:https://www.w3cschool.cn:8080/search?w=ajax

    • https是协议;
    • www.w3cschool.cn是域名;
    • 8080是端口号;
    • /search是路径;
    • ?w=ajax是 URL 地址带的参数;
    • 缺少 fragment 信息片段;

    什么是同源策略

    同源策略是一种安全协议,是客户端脚本(尤其是 JavaScript)中重要的安全度量标准,指一段脚本只能读取同一来源的窗口和文档的属性。

    何为同源?

    同源指的是 URL 地址中的 协议域名端口 三者 相同。

    路径不同,同源

    • www.w3cschool.cn
    • www.w3cschool.cn/tutorial
    • www.w3cschool.cn/minicourse/…

    协议不同,不同源

    • www.w3cschool.cn
    • www.w3cschool.cn

    域名不同,不同源

    • pm.w3cschool.cn
    • www.w3cschool.cn

    端口不同,不同源

    • www.pm.w3cschool.cn
    • www.pm.w3cschool.cn:445

    为什么要有同源策略

    我们在使用 Ajax 请求后端数据时,只能跟同源的后端接口进行数据交互,即:后端接口的 URL 与发起 Ajax 请求的页面 URL 之间,需要满足同源策略。

    不满足 "同源策略" 的请求浏览器通常都会报错,下面是一个 本地服务器 请求 远程服务器 产生的报错信息:

    Ajax(上)

    为了数据的安全性。若没有同源策略的限制,那么黑客就可以在他的页面上任意请求你的后端数据,造成数据库内容被盗取、隐私数据泄漏。

    跨域请求

    虽然 Ajax 请求需要满足同源策略,然而在一些场景中,你真的需要 Ajax 访问其它 "源" 的数据(称为跨域访问),这时需要后端服务器进行相应的设置。

    如果服务器端支持 CORS,可以通过设置Access-Control-Allow-Origin来实现跨域。如果浏览器检测到相应的设置,就会允许 Ajax 进行跨域访问。

    解决跨域的方式:

    • JSONP 技术
    • 在服务端设置代理模块;
    • 通过修改 window.name 实现跨域;
    • 使用 HTML5 中新引进的 window.postMessage 方法来跨域传送数据;
    • 等...

    XMLHttpRequest

    Ajax 技术的核心XMLHttpRequest类,简称 XHR,它允许脚本异步调用 HTTP API。浏览器在XMLHttpRequest类上定义了 HTTP API,这个类的每个实例都表示一个 独立请求/响应 对象,并且这个实例对象上的属性和方法允许 指定细节提取响应数据

    创建实例

    var xhr = new XMLHttpRequest();
    

    兼容

    绝大多数的浏览器都支持XMLHttpRequest在 IE7 之前的版本(IE5、IE6)并不支持XMLHttpRequest()构造函数,它们需要使用ActiveX对象进行模拟:

    var xhr = new ActiveXObject("Microsoft.XMLHTTP");
    

    兼容写法

    var xhr = window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
    

    open()

    创建 XMLHttpRequest 对象之后,发起 HTTP 请求的下一步是调用 XMLHttpRequest 对象的open方法,指定 HTTP 请求的两个必需部分:请求方法URL

    xhr.open(method, url, async)

    • method:

      • 第一个参数用于指定 HTTP 请求的方法,不区分大小写;

      • 该参数可取的值包括:"GET"、"POST"、"HEAD"、"PUT"、"OPTIONS"、"DELETE",其中,"GET" 和 "POST" 是得到广泛支持的请求方法;

    • url:

      • 第二个参数用于指定 HTTP 请求的 URL 地址,可以是 绝对URL相对URL

      • 绝对URL:需要满足 "同源策略"(服务器明确允许跨域请求的情况除外);

      • 相对URL:即相对于文档的 URL;

    • async:

      • 第三个参数是可选的,可用布尔值指定脚本是否以异步的方式调用此次 Ajax 请求;

      • 该参数默认为 true,表示异步调用此次 Ajax 请求,不阻塞后续脚本的执行;

    注意

    open()方法其实还可以有第四、第五个参数,分别是用于 HTTP 请求访问认证的用户名和密码,使用它们需要在服务器做相应的配置,较为少用。

    setRequestHeader

    如果你的 HTTP 请求需要设置请求头,那么调用 open 方法之后的下个步骤就是设置它,使用的方法是:setRequestHeader

    // 在 open 方法之后设置请求头
    xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    

    xhr.setRequestHeader(name, value)

    • name:请求头名称;
    • value:请求头的值。

    send()

    使用 XMLHttpRequest 发起 HTTP 请求最后一步是指定可选的请求主体、并向服务器发送它,使用的方法是:send

    var xhr = new XMLHttpRequest();
    xhr.open("GET", "/statics/demosource/demo_get_json.php");
    
    // 由于GET请求,没有请求主体,所以在调用 send 方法时可以传递 null或省略这个参数;
    xhr.send(null);
    
    var xhr = new XMLHttpRequest();
    xhr.open("POST", "/statics/demosource/demo_post_json.php");
    
    // 把 msg 作为请求主体发送
    xhr.send(msg);
    
    1. POST 请求通常都拥有请求主体,可在 send 方法中指定它;
    2. POST 请求的请求主体,应该匹配 setRequestHeader方法所指定的 "Content-Type" 头。

    获取响应

    一个完整的 HTTP 响应由 状态码、响应头和 响应主体 组成,这三者都可以通过XMLHttpRequest对象提供的属性和方法获取。

    如何确定 HTTP 请求已经返回了响应内容呢?

    为了能够在 HTTP 响应准备就绪时得到通知,必须监听XMLHttpRequest对象上的readystatechange事件。但为了理解这个事件类型,需要先了解下readyState属性,因为该事件监听的是readyState属性值的改变。

    XMLHttpRequest对象上的readyState属性在 HTTP 请求过程中,会从 0 变到 4

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Tryrun 2</title>
    </head>
    <body>
        <button id="btn">点我观察 readyState 属性的改变</button>
        
        <script>
            var oBtn = document.getElementById("btn");
            oBtn.onclick = function () {
                //兼容处理
                var xhr = window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
                alert(xhr.readyState);//0
                xhr.onreadystatechange = function () {
                    alert(xhr.readyState);
                }
                xhr.open("GET", "/statics/demosource/demo_get_json.php");
                xhr.send();
            }
        </script>
    </body>
    </html>
    

    readyState 属性

    readyState属性是一个整数,它的值代表了不同的 HTTP 请求状态。

    • 0:初始值,表示请求未初始化,open方法尚未调用;
    • 1:启动请求,open 方法已经调用,但尚未调用 send 方法;
    • 2:请求发送,已经调用 send 方法,但尚未接收到响应;
    • 3:接收响应,已经接受到部分响应数据,主要是响应头;
    • 4:HTTP 响应完成,已经接收到全部响应数据,而且可以在客户端使用。

    每次readyState属性值的改变都会触发readystatechange事件,但只有readyState属性值为 4 时才是我们所关心的状态,因为只有这个状态才表示 HTTP 的响应准备就绪,可以真正意义上的结合服务器所响应的数据来实现我们的业务需求。

    发送请求规范

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Tryrun 3</title>
    </head>
    <body>
        <button id="btn">点我观察 readyState 属性的改变</button>
        <div id="tip"></div>
        
        <script>
            var oBtn = document.getElementById("btn"),
                oTip = document.getElementById("tip");
            oBtn.onclick = function () {
                var xhr = window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
                xhr.onreadystatechange = function () {
                    if (xhr.readyState === 4) {
                        oTip.innerText = "HTTP 响应完成";
                    }
                };
    
                xhr.open("GET", "/statics/demosource/demo_get_json.php");
                xhr.send();
            }
        </script>
    </body>
    </html>
    

    注意

    • readyState的属性值只代表此时的 HTTP 请求处于哪个阶段:是发送了请求还是未发送请求,是只接收到了响应头还是响应完成;
    • "响应完成" 只代表 HTTP 请求结束,至于服务器的响应状态:是请求成功还是请求错误,又或者是服务器错误,需要通过 HTTP 状态码判断,它存储在XMLhttpRequeststatus属性上;

    status属性

    status属性会以数字的形式保存服务器响应的 HTTP 状态码,诸如使用最频繁的 "200" 表示请求成功,"404" 表示 URL 不能匹配服务器上的任何资源。

    HTTP 状态码是用来表示网页服务器响应状态的 3 位数字代码,所有状态码的第一个数字代表了响应的五种状态之一:

    • 1xx:临时响应
    • 2xx:成功
    • 3xx:重定向
    • 4xx:请求错误
    • 5xx:服务器错误

    哪些 HTTP 状态码表示我们可以获取到 HTTP 响应数据呢?

    2开头的状态码304。2开头的状态码都表示请求成功,而 304 是对客户端可读取缓存的一种响应,同样能获取到 HTTP 的响应数据。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Tryrun 4</title>
        <style>
            #btn { margin-top: 7px; }
        </style>
    </head>
    <body>
        <div id="tip"></div>
        <button id="btn">点我发起 Ajax 请求</button>
        
        <script>
            var oBtn = document.getElementById("btn"),
                oTip = document.getElementById("tip");
    
            oBtn.onclick = function () {
                var xhr = window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
    
                xhr.onreadystatechange = function () {
                    if (xhr.readyState === 4) return;
                    if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
                        oTip.innerText = "HTTP 请求成功";
                    }
                };
    
                xhr.open("GET", "/statics/demosource/demo_get_json.php");
                xhr.send();
            }
        </script>
    </body>
    </html>
    

    responseText 属性

    responseText属性以字符串的形式存储了响应主体,即:服务器的响应数据。

    无论返回的数据类型是什么,响应主体的内容都会保存在responseText属性中;

    响应html

    var xhr = new XMLHttpRequest();
    
    xhr.onreadystatechange = function () {
        if (xhr.readyState !== 4) return;
        if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
            // 当响应成功,获取响应数据,将数据赋值给本地
            oView.innerHTML = xhr.responseText;
        }
    };
    
    xhr.open("GET", "/statics/demosource/demo_get.php");
    xhr.send();
    

    响应json

    var xhr = new XMLHttpRequest();
    
    xhr.onreadystatechange = function () {
        if (xhr.readyState !== 4) return;
        if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
            // 使用JSON.parse把 响应数据转换为json数据
            var res = JSON.parse(xhr.responseText);
            // 将响应数据中的data属性赋值给oTime做内容
            oTime.innerText = res.data;
        }
    };
    
    xhr.open("GET", "/statics/demosource/demo_get_json.php");
    xhr.send();
    

    查询 HTTP 响应头的方法

    XMLHttpRequest对象上,可通过getAllResponseHeadersgetResponseHeader方法查询响应头信息。

    getAllResponseHeaders

    • getAllResponseHeaders方法无参数,用于一次性返回可查询的全部响应头信息
    var xhr = new XMLHttpRequest();
    
    xhr.onreadystatechange = function () {
        if (xhr.readyState !== 4) return;
        if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
            // 获取所有可查询的响应头信息
            oView.innerText = xhr.getAllResponseHeaders();
        }
    };
    
    xhr.open("GET", "/statics/demosource/demo_get_json.php");
    xhr.send();
    

    getResponseHeader

    • getResponseHeader方法用于查询单一响应头信息,需要传入一个指定 "头名称" 的字符串作为参数:getResponseHeader(headerName)
    var xhr = new XMLHttpRequest();
    
    xhr.onreadystatechange = function () {
        if (xhr.readyState !== 4) return;
        if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
            // 查询 "Content-Type" 响应头信息
            alert( xhr.getResponseHeader("Content-Type") );
        }
    };
    
    xhr.open("GET", "/statics/demosource/demo_get_json.php");
    xhr.send();
    

    注意

    由于XMLHttpRequest会自动处理 cookie,将 cookie 从getAllResponseHeaders方法返回的响应头集合中过滤掉,并且如果给getResponseHeader方法传递 "Set-Cookie" 或 "Set-Cookie2",则返回 null。

    同步响应

    var xhr = new XMLHttpRequest();
    
    // 指定 open 方法的第三个参数为 false
    xhr.open("GET", "/statics/demosource/demo_get_json.php", false);
    
    // send 方法的调用将阻塞后面代码的执行,直到此次 HTTP 请求完成
    xhr.send();
    
    // 不再需要监听 readystatechange 事件
    if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
        oTime.innerText = JSON.parse(xhr.response).date;
    } else {
        // 如果请求不成功,就报错
        throw new Error(xhr.status);
    }
    

    abort 中止请求

    若 HTTP 请求的时间超出预期,可以调用XMLHttpRequest对象上的abort方法来中止 HTTP 请求。

    var xhr = new XMLHttpRequest();
    var timer = null;    // 用于存储定时器标识
    
    xhr.onreadystatechange = function () {
        if (xhr.readyState !== 4) return;
        if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
            clearTimeout(timer);    // 未超时则取消定时器
        }
    };
    
    xhr.open("GET", "/statics/demosource/demo_get_json.php");
    xhr.send();
    
    // 2秒后中止此次 GET 请求
    timer = setTimeout(function(){
        xhr.abort();
    }, 2000)
    

    起源地下载网 » Ajax(上)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元