探秘

您所在的位置:网站首页 原生的ajax如何使用视频 探秘

探秘

2024-06-04 01:31| 来源: 网络整理| 查看: 265

目录

🌐 原生ajax

1. 什么是AJAX?

2. AJAX的使用

2.1 创建XHR对象

2.2 向服务器发送请求

2.3 服务器响应

2.4 onreadystatechange 事件

3. 手写一个简易的AJAX

🌐 现代AJAX的使用方式

1. jQuery封装的ajax

2. fetch API

3. axios

🌐 原生ajax

现代浏览器,最开始与服务器交换数据,都是通过XMLHttpRequest对象。它可以使用JSON、XML、HTML和text文本等格式发送和接收数据。

多年来,XMLHttpRequest一直是web开发者的亲密助手。无论是直接的,还是间接的, 当我们谈及Ajax技术的时候,通常意思就是基于XMLHttpRequest的Ajax,它是一种能够有效改进页面通信的技术。 Ajax的兴起是由于Google的Gmail所带动的,随后被广泛的应用到众多的Web产品(应用)中,可以认为, 开发者已经默认将XMLHttpRequest作为了当前Web应用与远程资源进行通信的基础。

1. 什么是AJAX?

AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML),意思是异步网络请求。区别于传统web开发中采用的同步方式。

AJAX 不是新的编程语言,而是一种使用现有标准的新方法。

AJAX 是与服务器交换数据并更新部分网页的艺术,在不重新加载整个页面的情况下。

Ajax带来的最大影响就是页面可以无刷新的请求数据。以往,页面表单提交数据,在用户点击完”submit“按钮后,页面会强制刷新一下,体验十分不友好。 有很多使用 AJAX 的应用程序案例:新浪微博、Google 地图、开心网等等。 可以这么说AJAX的出现极大了推动了前端的发展。

2. AJAX的使用 2.1 创建XHR对象

所有现代浏览器均支持 XMLHttpRequest 对象(IE5 和 IE6 使用 ActiveXObject)。XMLHttpRequest 用于在后台与服务器交换数据。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。 所有现代浏览器(IE7+、Firefox、Chrome、Safari 以及 Opera)均内建 XMLHttpRequest 对象。

let xmlhttp = new XMLHttpRequest()

老版本的 Internet Explorer (IE5 和 IE6)使用 ActiveX 对象:

let xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");

处理兼容性问题:

let xmlhttp; if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari xmlhttp = new XMLHttpRequest(); } else {// code for IE6, IE5 xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } 2.2 向服务器发送请求

向服务器发送请求就要用到XMLHtttpRequest对象的open和send方法

xmlhttp.open("GET","test1.txt",true); xmlhttp.send();

GET or POST ?

与 POST 相比,GET 更简单也更快,并且在大部分情况下都能用。

然而,在以下情况中,请使用 POST 请求:

无法使用缓存文件(更新服务器上的文件或数据库)向服务器发送大量数据(POST 没有数据量限制)发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠 2.3 服务器响应

如需获得来自服务器的响应,请使用 XMLHttpRequest 对象的 responseText属性。 responseText 属性返回字符串形式的响应,因此您可以这样使用:

document.getElementById("myDiv").innerHTML=xmlhttp.responseText; 2.4 onreadystatechange 事件

当请求被发送到服务器时,我们需要执行一些基于响应的任务。

每当 readyState 改变时,就会触发 onreadystatechange 事件。

readyState 属性存有 XMLHttpRequest 的状态信息。

下面是 XMLHttpRequest 对象的三个重要的属性:

属性描述onreadystatechange存储函数(或函数名),每当 readyState 属性改变时,就会调用该函数。readyState存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。- 0: 请求未初始化 1: 服务器连接已建立2: 请求已接收3: 请求处理中4: 请求已完成,且响应已就绪status200: "OK";404: 未找到页面 3. 手写一个简易的AJAX

这也算是面试中的一个高频考点了,虽然工作中不会中不会使用原生的AJAX而是使用封装好的AJAX,但是掌握基本原理还是必要的,这也应该是每位程序员的素养~

let xhr = new XMLHttpRequest(); xhr.open('GET', url, true) xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.status === 200) { console.log(xhr.responseText); }else{ console.log('404 NOT FOUND') } } xhr.send()

上面这种是最简易的,我们还可以结合Promise来实现,看下面一个版本👇

function ajax(url) { const p = new Promise((resolve, reject) => { let xhr = XMLHttpRequest() xhr.open("GET", url, true) xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.status === 200) { resolve(xhr.responseText) } else { reject(new Error("404 NOT FOUND")) } } xhr.send() }) return p }

番外:封装原生的请求

function obj2str(data) { data = data || {}; // 如果没有传参, 为了添加随机因⼦,必须⾃⼰创建⼀个对象 data.t = new Date().getTime(); var res = []; for (var key in data) { //在URL中是不可以出现中⽂的,如果出现了中⽂需要转码,可以调⽤encodeURIComponent⽅法,URL中 res.push(encodeURIComponent(key) + "=" + encodeURIComponent(data[key])); } return res.join("&"); } function ajax(option) { var str = obj2str(option.data); //key=value&key=value; var xmlhttp, timer; if (option.type.toLowerCase() === "get") { //toLowerCase将⼤写转化为⼩写 xmlhttp.open(option.type, option.url + "?" + str, true); xmlhttp.send(); } else { xmlhttp.open(option.type, option.url, true); //注意点:以下代码必须放在open和send之间 xmlhttp.setRequestHeader( "Content-type", "application/x-www-form-urlencoded" ); xmlhttp.send(str); } xmlhttp.onreadystatechange = function (ev2) { if (xmlhttp.readyState === 4) { clearInterval(timer); //判断是否请求成功(Http状态码⼤于等于200,且⼩于300,和状态码等于304为请求成功) if ( (xmlhttp.status >= 200 && xmlhttp.status < 300) || xmlhttp.status === 304 ) { option.success(xmlhttp); } else { option.error(xmlhttp); } } }; if (option.timeout) { timer = setInterval(function () { console.log("中断请求"); xmlhttp.abort(); clearInterval(timer); }, option.timeout); } }

使用:👇

ajax({ url:"http://server-name/login", type:'post', data:{ username:'username', password:'password' }, dataType:'json', timeout:10000, contentType:"application/json", success:function(data){    console.log(data); //服务器返回响应,根据响应结果,分析是否登录成功 }, //异常处理 error:function(e){ console.log(e); } })

 原生ajax的优点: 

不重新加载页面的情况下更新网页在页面已加载后从服务器请求/接收数据在后台向服务器发送数据。

原生ajax的缺点:

使用起来也比较繁琐,需要设置很多值。早期的IE浏览器有自己的实现,这样需要写兼容代码。 🌐 现代AJAX的使用方式

使用原生的js还是比较繁琐,实际工程中建议使用jQuery之类的库,封装的ajax请求方法非常好用,且解决了浏览器兼容性的问题。

1. jQuery封装的ajax

为了更快捷的操作DOM,并且规避一些浏览器兼容问题,产生了​​jQuery​​​。它里面的​​AJAX​​​请求也兼容了各浏览器,可以有简单易用的方法​​$.get​​​,​​$.post​​​。简单点说,就是对​​XMLHttpRequest​​对象的封装。

$.ajax({   type: 'POST',   url: url,    data: data,   dataType: dataType,   success: function () {},   error: function () {} })

jQuery-ajax的优点:

对原生​​XHR​​的封装,做了兼容处理,简化了使用。增加了对​​JSONP​​的支持,可以简单处理部分跨域。

jQuery-ajax的缺点:

如果有多个请求,并且有依赖关系的话,容易形成回调地狱。本身是针对MVC的编程,不符合现在前端MVVM的浪潮。ajax是jQuery中的一个方法。如果只是要使用ajax却要引入整个jQuery非常的不合理。

关于jQuery中的AJAX: 由于jQuery的使用频率已经很低了,关于jQuery中的AJAX如何使用,可以参看:jQuery中如何发送ajax请求以及解决跨域问题,当然,心有余力的小伙伴们可以自行查阅jQuery关于ajax的相关资料。

2. fetch API

fetch号称是AJAX的替代品,是在ES6出现的,使用了ES6中的promise对象。Fetch是基于promise设计的。Fetch的代码结构比起ajax简单多了,参数有点像jQuery ajax。但是,一定记住:fetch不是ajax的进一步封装,而是原生的js,没有使用XMLHttpRequest对象。

fetch是前端发展的一种新技术产物,是XMLHttpRequest的最新替代技术,它是W3C的正式标准

以下内容摘自mozilla:

Fetch API 提供了一个 JavaScript接口,用于访问和操纵HTTP管道的部分,例如请求和响应。它还提供了一个全局 fetch()方法,该方法提供了一种简单,合理的方式来跨网络异步获取资源。

这种功能以前是使用 XMLHttpRequest实现的。Fetch提供了一个更好的替代方法,可以很容易地被其他技术使用,例如 Service Workers。Fetch还提供了单个逻辑位置来定义其他HTTP相关概念,例如CORS和HTTP的扩展。

在使用fetch的时候需要注意:

当接收到一个代表错误的 HTTP 状态码时,从 fetch()返回的 Promise 不会被标记为 reject, 即使该 HTTP 响应的状态码是 404 或 500错误码(​​fetch只对网络请求报错,对​​400​​​,​​500​​都当做成功的请求,需要封装去处理)。相反,它会将 Promise 状态标记为 resolve (但是会将 resolve 的返回值的 ok 属性设置为 false ),仅当网络故障时或请求被阻止时,才会标记为 reject。默认情况下,fetch 不会从服务端发送或接收任何 cookies, 如果站点依赖于用户 session,则会导致未经认证的请求(要发送 cookies,必须设置 credentials 选项)。

​​​fetch​​​是低层次的API,代替​​XHR​​​,可以轻松处理各种格式,非文本化格式。可以很容易的被其他技术使用,例如​​Service Workers​​​。但是想要很好的使用​​fetch​​,需要做一些封装处理。

一个使用fetch获取数据的例子:👇

fetch('http://example.com/movies.json') .then(function(response) { return response.json(); }) .then(function(myJson) { console.log(myJson); });

fetch代表着更先进的技术方向,但是目前兼容性不是很好,在项目中使用的时候得慎重。

fetch 是比较新的技术,低版本浏览器和IE浏览器支持性不好 

fetch优点

①、语法简介,更加语义化 ②、基于标准的promise实现,支持async/await ③、同构方便,使用isomorphic-fetch ④、更加底层,提供的API丰富 ⑤、脱离了XHR,是ES规范里新的实现方式 ⑥、其考虑到了传输的文件比较大的时候的处理

fetch缺点

fetch 是一个低层次的API,你可以把它考虑成原生的XHR,所以使用起来并不是那么舒服,需要进行封装。

①、当接收到一个代表错误的 HTTP 状态码时,从 fetch() 返回的 Promise 不会被标记为 reject,即使响应的 HTTP 状态码是 404 或 500错误码。相反,它会将 Promise 状态标记为 resolve (如果响应的 HTTP 状态码不在 200 - 299 的范围内,则设置 resolve 返回值的 ok 属性为 false ),仅当网络故障时或请求被阻止时,才会标记为 reject。 ②、fetch 不会发送跨域 cookies(fetch​​​请求默认不会带​​cookie),需要添加配置项: fetch(url, {credentials: ‘include’}) ③、fetch不支持abort,不支持超时控制,使用setTimeout及Promise.reject的实现的超时控制并不能阻止请求过程继续在后台运行,造成了流量的浪费 ④、fetch没有办法原生监测请求的进度,而XHR可以

请注意,fetch规范与jQuery.ajax()主要有两种方式的不同,牢记:  

- 当接收到一个代表错误的 HTTP 状态码时,从 fetch()返回的 Promise 不会被标记为 reject, 即使该 HTTP 响应的状态码是 404 或 500。相反,它会将 Promise 状态标记为 resolve (但是会将 resolve的返回值的 ok 属性设置为 false ),仅当网络故障时或请求被阻止时,才会标记为 reject。 - 默认情况下,fetch 不会从服务端发送或接收任何 cookies, 如果站点依赖于用户 session,则会导致未经认证的请求(要发送 cookies,必须设置 credentials 选项)。

🙋‍♂️ 番外:为什么要使用fetch

XMLHttpRequest 是一个设计粗糙的 API,不符合关注分离(Separation of Concerns)的原则,配置和调用方式非常混乱,而且基于事件的异步模型写起来也没有现代的 Promise,generator/yield,async/await 友好。

Fetch 的出现就是为了解决 XHR 的问题,拿例子说明:

使用 XHR 发送一个 json 请求一般是这样:

var xhr = new XMLHttpRequest(); xhr.open('GET', url); xhr.responseType = 'json'; xhr.onload = function() { console.log(xhr.response); }; xhr.onerror = function() { console.log("Oops, error"); }; xhr.send();

使用 Fetch 后,顿时看起来好一点 

fetch(url).then(function(response) { return response.json(); }).then(function(data) { console.log(data); }).catch(function(e) { console.log("Oops, error"); });

使用 ES6 的 箭头函数 后: 

fetch(url).then(response => response.json()) .then(data => console.log(data)) .catch(e => console.log("Oops, error", e))

现在看起来好很多了,但这种 Promise 的写法还是有 Callback 的影子,而且 promise 使用 catch 方法来进行错误处理的方式有点奇怪。不用急,下面使用 async/await 来做最终优化: 

注:async/await 是非常新的 API,属于 ES7,这是它的完整规范。使用 Babel 开启 runtime 模式后可以把 async/await 无痛编译成 ES5 代码。也可以直接使用 regenerator 来编译到 ES5。

// 注:这段代码如果想运行,外面需要包一个 async function try { let response = await fetch(url); let data = response.json(); console.log(data); } catch(e) { console.log("Oops, error", e); }

duang~~ 的一声,使用 await 后,写异步代码就像写同步代码一样爽。await 后面可以跟 Promise 对象,表示等待 Promise resolve() 才会继续向下执行,如果 Promise 被 reject() 或抛出异常则会被外面的 try...catch 捕获。

Promise,generator/yield,await/async 都是现在和未来 JS 解决异步的标准做法,可以完美搭配使用。这也是使用标准 Promise 一大好处。最近也把项目中使用第三方 Promise 库的代码全部转成标准 Promise,为以后全面使用 async/await 做准备。

另外,Fetch 也很适合做现在流行的同构应用,有人基于 Fetch 的语法,在 Node 端基于 http 库实现了 node-fetch,又有人封装了用于同构应用的 isomorphic-fetch。

注:同构(isomorphic/universal)就是使前后端运行同一套代码的意思,后端一般是指 NodeJS 环境。

3. axios

首先,你需要知晓:axios并不是一种新的技术,而只是一种技术方案。

axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,本质上也是对原生XHR的封装,只不过它是Promise的实现版本,符合最新的ES规范,有以下特点:

从浏览器中创建 XMLHttpRequests从 node.js 创建 http 请求支持 Promise API拦截请求和响应转换请求数据和响应数据取消请求自动转换 JSON 数据客户端支持防御 XSRF提供了一些并发请求的接口(重要,方便了很多的操作)

axios的使用方法

// 为给定 ID 的 user 创建请求 axios.get('/user?ID=12345') .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); }); // 上面的请求也可以这样做 axios.get('/user', { params: { ID: 12345 } }).then(function (response) { console.log(response); }).catch(function (error) { console.log(error); });

关于更多axios的使用,大家请参考: axios官方文档​​​​​​

浏览器支持

axios面向现代浏览器设计(只支持现代浏览器),所以,古老的浏览器并不支持。

因为axios设计简洁,API简单,支持浏览器和node,所以大受欢迎。它能很好的与各种前端框架整合。因此,推荐大家在项目中使用axios库。

目前来看axios算是比较完美的一种方案了,几乎没有什么大的缺陷。

小结:

原生XHR几乎很少开发会用,JqueryAjax属于老当益壮的那种,虽然很老,但是很好用,Fetch是属于初生牛犊,还需要慢慢成长,axios就目前来说,算是非常好的了,无脑使用即可。

参考资料:Ajax、fetch、axios的区别与优缺点



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3