基于原生JS实现AJAX

// 1.创建一个ajax对象
let xhr = new AMLHttpRequest();// 不兼容IE6及更低版本的浏览器(IE6:ActiveXObject)
// 2.打开请求地址(可以理解为一些基础配置,但没有发送请求)
xhr.open([method], [url], [async], [username], [user password])
// 3.监听AJAX状态改变,获取响应信息(获取响应头信息、获取响应主题信息)
xhr.onreadystatechange=()=>{
  if(xhr.readyState === 4 && xhr.status === 200){
    let result = xhr.responseText; // 获取响应主体中的内容
    
  }
};
// 4. 发送ajax请求(括号中传递的内容就是请求主体的内容)
xhr.send(null);

第二步中的知识点

xhr.open([method], [url], [async], [username], [user password])
[method]: HTTP请求方式,不管哪一种请求方式,客户端都可以传递一些信息给服务器,服务器也可以返回一些信息给客户端,GET系列以获取为主(给的少拿的多),POST系列以推送为主(给的多拿的少)
1)GET系列请求方式(获取)

  • get
  • delete:从服务器上删除某些资源文件
  • head:只获取返回的响应头信息(不要响应主体内容)
  • ...

2)POST系列请求方式(推送)

  • post
  • put:向服务器中增加指定的资源文件
  • ...

A. 获取一些动态展示信息,一般使用GET请求,只需要向服务器端发送请求,告诉它需要的数据,服务器端就会返回需要的数据
B. 实现注册功能的时候,需要把客户输入的信息发送给服务器进行存储,服务器一般返回成功失败等状态,一般用POST请求完成

GET系列请求和POST系列下请求的区别
1、GET请求传递给服务器的内容一般没有POST请求传递的多
原因:GET请求给服务器传递内容一般都是基于url地址问号传递参数来实现,而POST请求是设置请求主体来实现,各浏览器对URL的长度都有限制,超过限制浏览器会自动截取,这样传递的数据就会出现缺失
理论上POST通过请求主体传递参数是没有大小限制的,真实项目中为了保证传输的速率也会限制大小(例如上传资料、图片都会做大小限制)
2、GET请求会出现缓存,POST不会出现
原因:GET通过URL传参(可能几次请求一样),POST是设置请求主体

// 每隔一分钟重新请求服务器端的最新数据展示在页面中(页面中某些数据实时刷新)
setTimeout(()=>{
  $.ajax({
    url: 'getUserInfo?id=123',
    ...
    success:result=>{
      // 第一次请求数据回来,一分钟后浏览器又发生一次请求,但新发送的请求跟上次一模一样,
      //浏览器很有可能会直接获取上一次的数据
    }
});
}, 60000);

//=> 解决方案 每次在url末尾追加一个随机数,就能保证每次请求的url不一样
// HTTP相关里头有提到
setTimeout(()=>{
  $.ajax({
    url: 'getUserInfo?id=123&_='+Math.random(),
    ...
    success:result=>{
    }
});
}, 60000);

3、GET请求没有POST请求安全(相对安全)
原因:还是因为GET是URL传参
URL劫持,可以把客户端传递给服务器的数据劫持掉,导致信息泄露

[url]: 请求数据的地址(API地址),真实项目中,后台开发工程师会编写一个API文档,文档汇总了获取数据需要用的地址,按照文档操作即可
[ASYNC]: 异步(SYNC同步),默认true,表示异步
[username password]: 一般不用的两个参数 若请求的URL地址所在的服务器设定了访问权限,则需要提供用户名密码,否则不需要

第三部分细节

xhr.onreadystatechange=()=>{
  if(xhr.readyState === 4 && xhr.status === 200){
    let result = xhr.responseText; // 获取响应主体中的内容
    
  }
};

AJAX状态码:描述当前AJAX操作的状态
xhr.redayState

0:UNSEND 未发送,只要创建AJAX对象,默认就是0
1: OPENED 执行了xhr.open这个操作
2:HEADERS_RECEIVED 当前AJAX请求已经发送,并且已经接收到服务器端返回的响应头信息
3:LOADING 响应主体内容正在返回的路上
4:DONE 响应主体内容已经返回到客户端


HTTP网络状态码,记录当前服务器返回信息的状态
xhr.status

200:成功 一个完整的HTTP事务完成(以2开头的状态码一般都是成功)

以3开头的一般也是成功,只不过服务器端做了很多特殊的处理
301: Moved Permanently 永久转移(重定向) 一般用于域名迁移
302: Moved Temporarily 临时转移(新的HTTP版本中307是临时重定向)一般用于服务器的负载均衡:当前服务器处理不了,把当前请求临时交给其他服务器处理
304: Not Modified 从浏览器缓存中获取数据 把一些不经常更新的文件或内容缓存到浏览器中,下次可直接从缓存中获取,减轻服务器压力,提高页面加载速度

以4开头的一般都是失败,且一般都是客户端的问题(没拿到数据)
400:请求参数错误
401:无权限访问
404:访问地址不存在>

以5开头的一般都是失败,且一般都是服务器端的问题(没拿到数据)
500:Internal Server Error未知的服务器错误
503:Service Unavailable服务器超载

AJAX中其他常用的属性和方法

面试题:AJAX中常用的方法有几个(AJAX总共支持几个方法)?

let xhr = new XMLHttpRequest();
console.dir(xhr);
[属性]
1、readyState:存储的是当前AJAX状态码(01234)
2、responseText/responseXML/response:都是用来接收服务器返回的响应主体的内容,只是根据服务器返回内容的格式不一样,使用不同属性接收

  • responseText最常用,接收到的结果是字符串格式(服务器一般返回的都是JSON格式字符串)
  • responseXML偶尔用到,若服务器端返回XML文档数据,就用这个属性接收

3、status:记录了服务器端返回的HTTP状态码
4、statusText:对返回状态码的描述(200:ok)
5、timeout:设置当前AJAX请求的超时时间,假设设置为3000(ms),3秒后响应主体内容还没返回,浏览器就会强制断开请求

[方法]
1、abort():强制中断请求
2、getAllResponseHeaders():获取全部响应头信息(结果是一堆字符串文本)
3、getResponseHeader(key):获取指定属性名的响应头信息。例如getResponseHeader('date')获取响应头中存储的服务器时间
4、open():打开一个url地址
5、send():发送AJAX请求,参数客户端设置的请求主体
6、setRequestHeader(key,value):设置自定义的请求头信息

[事件]
1、onabort: AJAX被中断请求时触发事件
2、onreadystatechange: AJAX状态码发生改变时触发事件
3、ontimeout: AJAX请求超时触发事件

let xhr = new XMLHttpRequest();
xhr.open('get', 'temp.json?_='+Math.random(), true);
xhr.setRequestHeader('cookie', 'cache'); //不能是汉字
// 请求头必须在open之后,send之前设置
xhr.timeout = 1;
xhr.ontimeout = () => {
    console.log("请求超时");
    xhr.abort();
};
xhr.onreadystatechange = () => {
    let {readyState:state, status} = xhr;
    // 请求成功  以2或3开头的后面两位数字
    if(! (/^(2|3)\d{2}$/).test(status)) return;
    // 状态为2时就可以获取头信息
    if(state === 2){
        let headAll = xhr.getAllResponseHeaders(),
            serverDate = xhr.getResponseHeader("date");
        // 时间是格林尼治时间差8小时 new Date转化为北京时间
        console.log(headAll, new Date(serverDate));
        return;
    }
    if(state === 4){
        let valueText = xhr.responseText, // 获取的结果,一般都是字符串
            valueXML = xhr.responseXML; //获取到XML格式数据
        console.log(valueText, valueXML);
    }
};
xhr.send(null);

AJAX中的同步和异步

AJAX这个任务:发送请求接收到响应主体接收完成 这个事务才算完成

let xhr = new XMLHttpRequest();
xhr.open('get', 'temp.json', false);
xhr.onreadystatechange = () => {
    console.log(xhr.readyState);
    // 只输出4
};
xhr.send(null);

////////分割线//////////

let xhr = new XMLHttpRequest();
xhr.open('get', 'temp.json', false);
xhr.send(null); //=> [同步]开始发送AJAX请求,任务没有完成之前下面事情做不了,
// 当xhr.readyState===4时,开始执行下面的操作
// 这个方法已经不会被触发
xhr.onreadystatechange = () => {
    console.log(xhr.readyState);
    // 不输出任何东西 无法获取响应主体的内容
};

////////分割线//////////

let xhr = new XMLHttpRequest();
xhr.open('get', 'temp.json'); // 第三个参数不写默认true
xhr.onreadystatechange = () => {
    console.log(xhr.readyState);
    // 2 3 4
};
xhr.send(null);

////////分割线//////////

let xhr = new XMLHttpRequest();
xhr.open('get', 'temp.json');
xhr.send(null);
// => xhr.readyState === 1
xhr.onreadystatechange = () => {
    console.log(xhr.readyState);
    // 2 3 4
};

////////分割线//////////

let xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
    console.log(xhr.readyState);
    //1 2 3 4
};
xhr.open('get', 'temp.json');
xhr.send(null);

////////分割线//////////

let xhr = new XMLHttpRequest();
//xhr.readyState === 0
xhr.onreadystatechange = () => {
    console.log(xhr.readyState);
    // 1 4
};
xhr.open('get', 'temp.json', false); 
// AJAX特殊处理了一件事,状态变为1会主动执行监听方法,然后再send
// xhr.readyState === 1
xhr.send(null);
// xhr.readyState === 4 主任务队列完成

AJAX类库的封装

JQ 中的AJAX

$.ajax({
  url: 'xxx.json', //=> 请求地址
  method: 'get', //=> 请求方式 老版本中method和type一样 
  dataType: 'json', //=>只是预设获取结果的数据类型,不会影响服务器的返回
  // 服务器返回的都是JSON格式的字符串
  cache: false, //=>只对GET系列有作用,默认为true, 
  //手动设置为false, JQ会在URL的末尾追加一个随机数来清除缓存
  data: null, //=>通过data可以把一些信息传递给服务器
  // GET系列请求会把data的内容拼接在URL末尾传递给服务器
  // POST会把data的内容放在请求主体中
  // 可以是两种格式:字符串、对象,若是字符串,设置什么就传递什么;
  // 若是对象,JQ会设置成"键=值"形式的字符串传递给服务器
  async: true, //=>设置同步或者异步,默认true是异步
  success: function(result){
    //=> AJAX请求成功触发这个函数执行(readyState=4&&status==2/3开头的)
    //=> result 就是获取到的结果
  },
  error: function(msg){
     // =>请求错误触发该函数
  },
  complete: function(){
    //=> 完成就触发,不管对或错
  },
});
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容

  •   2005 年,Jesse James Garrett 发表了一篇在线文章,题为“Ajax: A new App...
    霜天晓阅读 881评论 0 1
  • AJAX 原生js操作ajax 1.创建XMLHttpRequest对象 var xhr = new XMLHtt...
    碧玉含香阅读 3,146评论 0 7
  • 27、移动端响应式布局开发 响应式布局开发 1、什么是响应式布局开发?把我们开发完成的产品,能够让其适配不同的设备...
    萌妹撒阅读 1,033评论 0 0
  • 1、XMLHttpRequest 对象 在浏览器中创建XHR 对象 1.1 XHR 的用法 在使用XHR 对象时,...
    shanruopeng阅读 577评论 0 1
  • Ajax:Asynchronous JavaScript + XML的简写。Ajax技术的核心是XMLHttpRe...
    exialym阅读 866评论 0 8