AJAX异步请求

AJAX即Asynchronous Javascript And XML,指异步JavaScript和XML的HTTP网络请求。AJAX异步HTTP请求在浏览器前端开发中应用十分广泛,我们知道传统网页是同步式的,一次HTTP请求响应一个HTML页面,而AJAX则是异步发起HTTP请求,根据返回结果的XML数据进行DOM或其他操作,整个HTML页面不用刷新即可动态更新展示数据,因此能够实现极其复杂的交互体验。

注:随着技术发展,现在我们更倾向于使用JSON作为数据交换格式,而非之前曾风靡一时的XML格式。

XMLHttpRequest(XHR)

XMLHttpRequest对象是AJAX技术的核心,它用于发起异步请求。

方法

  • open(method, url, async):参数为请求类型,资源URL,同步还是异步(实际上只能取true
  • send(str):异步发送消息,参数为发送的请求体字符串,参数仅用于POST,GET时send无参数即可
  • setRequestHeader(header, value):设置请求头信息,例如:提交表单需要设置请求头为xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")

属性

  • responseText:服务器的响应字符串
  • responseXML:服务器响应的XML,和responseText的区别是responseXML返回的是XMLDocument对象,直接使用DOM解析即可。
  • onreadystatechange:每次readystate改变都回调对应的函数
  • readystate参数:
  • 0:请求未初始化
  • 1:服务器已建立连接
  • 2:请求已接收
  • 3:请求处理中
  • 4:请求已完成
  • status:状态码,如200表示请求成功,正常完成

AJAX使用实例

下面代码展示了XHR如何发起GET请求。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo AJAX</title>
</head>
<body>
    <button onclick="ajax()">click</button>
    <div id="div"></div>
    <script>
        function ajax()
        {
            var xhr = new XMLHttpRequest();
            xhr.open("GET", "test.txt");
            xhr.send();
            xhr.onreadystatechange = function()
            {
                if(xhr.readyState == 4 && xhr.status == 200)
                {
                    document.querySelector("#div").innerHTML = xhr.responseText;
                }
            };
        }
    </script>
</body>
</html>

上面代码中,当我们点击按钮,XHR会异步请求test.txt的内容,将其以文本形式显示到<div>中。

FetchAPI

在最新的浏览器中,引入了一个独立于XHR的全新AJAX接口FetchAPI。下面是一段例子代码,实现了上方代码完全同样的功能。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo AJAX</title>
</head>
<body>
<button onclick="ajax()">click</button>
<div id="div"></div>
<script>
    function ajax()
    {
        fetch('test.txt').then(
            rsp => rsp.text().then(
                txt => document.querySelector("#div").innerHTML = txt
            )
        );
    }
</script>
</body>
</html>

FetchAPI相比XHR使用更加方便,其API设计上更为先进。然而FetchAPI的兼容性在目前来说仍有较大问题,IE浏览器全部版本(包括最新的IE11)都不支持FetchAPI,具体使用时需要注意这一点。

AJAX相关库

  • JQuery:JQuery库可以说是相当强大的一个库,包含了前端开发必备的各种功能,其对XHR有一套良好的封装
  • Axios:这个库封装了冗长的XHR,而写法类似FetchAPI,Axios非常轻巧好用而且还保证了兼容性,在现代前端项目开发中,如果完全不使用JQuery,实现AJAX时Axios是一个不错的选择
  • Polyfill:Polyfill是一个能让旧浏览器用兼容性方式实现新功能(如FetchAPI)的库,功能非常强大也非常实用

常见问题

URL参数路径

无论XHR还是Fetch,这个URL参数的写法和页面中的资源路径是完全一致的,例如当前URL是http://a.com/b/:如果请求http://xxx.com/xxx,这是绝对路径,浏览器直接请求该路径;如果是/xxx.txt/代表网站根目录,因此请求http://a.com/xxx.txt;如果是xxx.txt,则请求同级目录下的xxx.txt,即http://a.com/b/xxx.txt

AJAX跨域问题

浏览器中AJAX是不允许跨域请求的,这是出于安全考虑而做出的限制。JavaScript能够读取CookieWeb StorageindexedDB等应用数据,如果能够跨域请求,当页面被xss攻击时,这些信息就会泄露。

然而,实际开发中有时候确实有AJAX跨域访问的需求,这时可以考虑在服务器端加上CORS响应头、JSONP等手段解决。

AJAX上传文件

HTML5后,AJAX可以通过提交手动拼装的FormData对象实现异步的小文件上传,对于旧浏览器,则只能考虑构造一个隐藏的<iframe>来解决这个问题(写法非常不优雅)。JQuery有一个ajaxFileUpload插件,可以方便的解决文件上传功能的跨浏览器兼容问题。

对于较大文件,建议使用HTML5的ArrayBuffer等新功能来实现分块上传。

作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。