原生Ajax( XHR 和 Fetch )
原生Ajax 基本使用的四大步骤,简单易懂
什么是ajax?
ajax(异步javascript xml) 能够刷新局部网页数据而不是重新加载整个网页。
如何使用ajax?
一般大家都把所用ajax分为4个步骤,但是我觉得应该是3个步骤。(注意:ajax执行步骤不等于执行顺序,官方都是把步骤三事件函数写在步骤二的前面)
第一步: 创建 XMLHttpRequest 对象
var xmlhttp; if (window.XMLHttpRequest) { // IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码 xmlhttp=new XMLHttpRequest(); } else { // IE6, IE5 浏览器执行代码 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); }
第二步:向服务器发送请求请求
GET请求
xmlhttp.open("GET","/try/ajax/demo_get.php",true); xmlhttp.send();
在上面的例子中,您可能得到的是缓存的结果。
为了避免这种情况,请向 URL 添加一个唯一的 ID:
xmlhttp.open("GET","/try/ajax/demo_get.php?t=" + Math.random(),true); xmlhttp.send();
POST请求
xmlhttp.open("POST","/try/ajax/demo_post.php",true); xmlhttp.send();
如果需要像 HTML 表单那样 POST 数据,请使用 setRequestHeader() 来添加 HTTP 头。然后在 send() 方法中规定您希望发送的数据:
xmlhttp.open("POST","/try/ajax/demo_post2.php",true); xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"); xmlhttp.send("fname=Henry&lname=Ford");
第三步:onreadystatechange 事件
xmlhttp.onreadystatechange=function() { if (xmlhttp.readyState==4 && xmlhttp.status==200) { document.getElementById("myDiv").innerHTML=xmlhttp.responseText; } }
注:1、每当 readyState 改变时,就会触发 onreadystatechange 事件。(readyState 属性存有 XMLHttpRequest 的状态信息)
2、实测 如果第三步的代码在第二步之前则onreadystatechange 事件被触发 4 次(0 - 4), 分别是: 0-1、1-2、2-3、3-4,对应着 readyState 的变化;
如果第三步在第二步后面则onreadystatechange 事件被触发 3 次(0 - 4), 分别是: 1-2、2-3、3-4,对应着 readyState 的变化(这种情况的原因是当readyState 从0-1变化时,js从上到下执行代码时,onreadystatechange 事件的执行函数还没定义,所以0-1的变化没法触发onreadystatechange 事件)。 【这应该就是 http的 3次握手,4次挥手的过程】
3、一般认为的第三步:
一般的资料中都把 服务器 响应 (获得来自服务器的响应,使用 XMLHttpRequest 对象的 responseText 或 responseXML 属性) 作为第三步,但是个人认为这个不应该作为开发的步骤,而是ajax对象返回的数据。
1、详解Ajax请求(四)——多个异步请求的执行顺序 :(多个ajax回调函数执行的顺序不一定是从上到下的)
https://www.cnblogs.com/cdf-opensource-007/p/6371237.html
2、凡是 要 用到ajax返回数据的代码,必须在ajax的回调函数中执行。因为ajax是异步执行的,当ajax数据 还没回来,其它的代码都执行了,这个时候外面的代码用到这个数据,就会报错。
3、ajax请求是异步的,发送请求后需要跳页(重定向)的话(如:提交按钮),跳转页面一定要放在ajax的回调函数里面,不然会导致ajax请求失败。因为ajax数据还没返回来(ajax异步执行,js进程不管ajax怎么样了,继续执行下面的代码),js就执行下面的跳页,这个时候后台数据返回来,无法传递到对应的请求url中。虽然执行了
window.location.href = "./**/*.html";语句,但是后面的代码还是会继续执行的,ajax长时间没有接受到返回的信息,就会执行 error(jQuery库)中的代码。
注:至于window.location.href = "./**/*.html"; 已经跳页了,为什么后面代码还会继续执行的问题,有时间在去了解。
4、location.href页面跳转后禁止后续操作 : http://baijiahao.baidu.com/s?id=1569994757645432&wfr=spider&for=pc
5、document.location和window.location有什么区别
参考:https://bbs.csdn.net/topics/330028654
(个人)一般情况都是一样使用的,但是在iframe里面区别就出来了。
6、window.location.href = “ ”,这个重定向后面的代码还是会执行的。 (这个问题可以当做js的一个bug,没有必要深入了解,把这条语句放在最后面执行就可以了。异步操作后执行的就放在回调函数中执行)
原因参考:https://www.zhihu.com/question/29890952?from=profile_question_card (没有解释清楚)
setTimeout(function(){ window.location.href = "./**/*.html"; alert("0"); alert("1"); alert("2"); },9000);
7、ajax请求中,无论后台返回的什么类型的数据,前端浏览器 返回的都是字符串类型(整体是string类型)。json格式化字符串转换为对应的对象(或 字符串类型 或 数值类型) 数据。
注意: '{ "name": "cxh", "sex": "man" }' 形式数据是json字符串; { "name": "cxh", "sex": "man" } 形式数据是json对象,不是字符串。
不管是json对象还是json字符串,它们的属性名必须加双引号。
后端返回的 { "name": "cxh", "sex": "man" } 类型数据,就是json字符串,因为后端返回的数据到前端后都是字符串类型。 参考链接
8、注意 ajax请求的url参数是可以相对路径的:https://blog.csdn.net/hys1253731584/article/details/79503011
绝对路径的url,也可以省略前面的域名端口的,看起来像相对路径。即 ajax请求同源的 API 接口,绝对路径也可以不写 协议、域名、端口的。
9、ajax 请求,是获取使用的数据,有时是要判断下(或try...catch),是否有数据(如获取选手信息。调接口,发送选手id这个参数,后台查询后,返回成功,但是数据为空),否则直接使用一个未定义对象 的方法或属性是会报错的。
如果是有捕获函数catch的话,则不会报错,但会执行catch内的函数,这不是想要的逻辑。
如: axios 请求中的catch函数(catch函数是在服务器报错,才执行的函数。服务器成功是200)。服务器返回200成功,但是因为js报错导致执行catch函数。这样我们就会以为是服务器的问题,实际上服务器是好的。
关键点: 如果 后端程序,对这个参数是否有效做了判断,返回其它的errorCode值,前端完全可以不用判断是否有返回数据。后端程序,直接拿一个数据库中没有的 选手id参数 去查找相应的 信息,肯定没有数据,返回数据到了前端页面,对应的字段就没有了。
// 调接口后 执行的函数
if (res.errorCode === 0) { document.title = res.data.playName // 这里 没有查询到数据,返回的对象里就没有data这个属性了。这里会直接报错 }
// 查询不到这选手信息,返回的数据 { errorCode: 0, success: true, value: "查询成功" }
正常查询到数据后,返回的数据是 下面这样的
{ data: { playName: "张三", age: 20, }, errorCode: 0, value: "查询成功", success: true }
ajax的 file类型参数
1、ajax的参数如果需要发送的是文件(即文件流),直接填url肯定的没用的,那只是一个字符串。我们可以通过发起本地文件的网络请求,就可以获取到对应文件的数据流了。
(个人)分析:涉及文件 的前后端交互,有两种方案。
一 种是ajax把对应文件(如图片)的url地址作为参数发给后台服务器,由服务器对这个图片文件发起网络请求,获得数据流。(这种方式要求,图片文件必须在某个服务器上,后台服务器发起网络请求可以获得对应的文件),
第二种,就是发起本地网络请求,获得对应文件的数据流。(这种方式开发中用的比较多,一般开发都是在本地。)
注意:ajax请求的对象(一般是文件)必须是在服务器中,即请求协议不能是 file:// 这种协议的。
2、get请求图片,回调中返回的数据是一个文件流对象。ajax的参数必须的字符串,不能是对象(待验证)。
3、jQuery中ajax各个参数 : https://www.cnblogs.com/qiufuwu618/archive/2012/12/20/2826190.html
原生 Fetch:https://www.jianshu.com/p/7762515f8d1a
1、fetch 本身就是 基于 promise 实现的,而ajax要使用promise的功能,必须先转化为promise对象。
2、目前 fetch 使用的不是很多,后期在行补充