Ajax( Asynchronous Javascript And XML)

注意同步和异步的区分

  • 同步 sync: 首先,JS 是单线程的语言,所谓“单线程”就是一根筋,对于拿到的程序,一行一行的执行,前面的执行完成,后面的傻傻的等着。若前面的代码没执行完就会造成堵塞,后面的没法执行。

  • 异步 async: 而AJAX 是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。异步代码执行的时候就不会阻塞后面的代码执行。

  • 记住: 同步执行代码总是优先于异步执行代码,同步代码在异步代码之前执行。

    • 因为碰到异步代码时,会将异步代码另行存到一个异步队列里面,然后将这个异步队列放到同步代码的最后,才执行
      例如:Ajax和setTimeout和setInterval这些是异步执行的

Ajax 优势:

1.不需要插件支持(一般浏览器且默认开启 JavaScript 即可);
2.用户体验极佳(不刷新页面即可获取可更新的数据);
3.提升 Web 程序的性能(在传递数据方面做到按需放松,不必整体提交);
4.减轻服务器和带宽的负担(将服务器的一些操作转移到客户端);

Ajax 的不足:

1.不同版本的浏览器度 XMLHttpRequest 对象支持度不足(比如 IE5 之前);
2.前进、后退的功能被破坏(因为 Ajax 永远在当前页,不会记录前后页面);
3.搜索引擎的支持度不够(因为搜索引擎爬虫还不能理解 JS 引起变化数据的内容);

json是一种数据格式,由对象,数组互相嵌套组成,属性名必须加双引号,数据传输格式

ajax.readyState:

0 - (未初始化)还没有调用send()方法
1 - (载入)已调用send()方法,正在发送请求
2 - (载入完成)send()方法执行完成,已经接收到全部响应内容
3 - (交互)正在解析响应内容
4 - (完成)响应内容解析完成,可以在客户端调用了

HTTP 状态码 ajax.status

101——客户要求服务器根据请求转换HTTP协议版本
200——交易成功
304——客户端已经执行了GET,但文件未变化
306——前一版本HTTP中使用的代码,现行版本中不再使用
400——错误请求,如语法错误
404——没有发现文件、查询或UR
405——用户在Request-Line字段定义的方法不允许
500——服务器产生内部错误
505——服务器不支持或拒绝支请求头中指定的HTTP版本

GET,POST方式比较

只是不同的发送和请求数据的方式
GET:参数有长度限制,http://www.taobao?id=… , 明文传输
POST:参数无限制,放在请求体里, 更安全

// get方式
var ajax = new XMLHttpRequest();
ajax.open("GET","url",true);
ajax.send(null);
ajax.onreadystatechange = function(){
if(ajax.readyState == 4 && ajax.status == 200){
     var json = JSON.parse(ajax.responseText);
    fn(json);
}

// post方式
var ajax = new XMLHttpRequest();
ajax.open("POST","url",true);
ajax.setRequestHeader("Content-type","application/x-www-form-urlencoded");
ajax.send("name=zhangsan&age=18");
ajax.onreadystatechange = function(){
if(ajax.readyState == 4 && ajax.status == 200){
     var json = JSON.parse(ajax.responseText);
    fn(json);
}

封装一个Ajax的get和post方式

ajax的get方式:

/* ajax请求get
 * @param url     string   请求的路径
 * @param query   object   请求的参数query
 * @param succCb  function 请求成功之后的回调
 * @param failCb  function 请求失败的回调
 * @param isJson  boolean  true: 解析json  false:文本请求  默认值true 
 */
ajaxGet : function (url, query, succCb, failCb, isJson) {
	// 拼接url加query
	if(query) {
		url += "?";
		for(var key in query){
			url += key+"="+query[key]+"&";
		}
		// 把最后一个&删掉
		url = url.slice(0, -1);
	}
	
	// 1、创建对象
	var ajax = new XMLHttpRequest();
	// 2、建立连接
	ajax.open("GET", url, true);
	
	// 3、发送请求
	ajax.send(null);
	
	// 4、监听状态的改变
	ajax.onreadystatechange = function(){
		if(ajax.readyState === 4){
			if(ajax.status === 200){
				// 用户传了回调才执行
				// isJson默认值为true,要解析json
				if(isJson === undefined){
					isJson = true;
				}
				var res = isJson ? JSON.parse(ajax.responseText) : ajax.responseText;
				succCb && succCb(res);
			}else{
				// 请求失败
				failCb && failCb();
			}
		}
	}
}

// 调用该方法实例:
//tools.ajaxGet("03-ajax.php", {"name": "lisi"}, function(res){console.log(res);}, function() {},false);

ajax的post方式:

/* ajax请求post
 * @param url     string   请求的路径
 * @param query   object   请求的参数query
 * @param succCb  function 请求成功之后的回调
 * @param failCb  function 请求失败的回调
 * @param isJson  boolean  true: 解析json  false:文本请求  默认值true 
 */
ajaxPost: function(url, query, succCb, failCb, isJson){
	var ajax = new XMLHttpRequest();
	ajax.open("POST", url, true);
	// 设置请求头数据传输格式
	ajax.setRequestHeader("Content-type","application/x-www-form-urlencoded");
	// 把query拼接成urlencoded
	var str = "";
	for(var key in query){
		str += key + "=" + query[key] + "&";
	}
	str = str.slice(0,-1);
	ajax.send(str);
	ajax.onreadystatechange = function () {
		if(ajax.readyState === 4) {
			if(ajax.status === 200){
				// 判断isJson是否传进来了
				isJson = isJson === undefined ? true : isJson;
				succCb && succCb(isJson ? JSON.parse(ajax.responseText) : ajax.responseText);
			}
		}
	}
}

// 调用该方法实例:
//tools.ajaxGet("03-ajax.php", {"name": "lisi"}, function(res){console.log(res);}, function() {},false);

同源策略:

浏览器安全策略,保障非同源资源之间数据访问的安全性。
默认不允许非同源的资源直接访问。
URL:
协议://域名:端口/路径名称?查询字符串#位置标识符
同源:协议、域名、端口完全一致,只要三个中有任何一个不一致,则是非同源
非同源资源间需要进行访问,则需要实现跨域。

解决资源跨域访问:

CORS

cross-origin resource sharing
服务器端:设置响应头信息:Access-Control-Allow-Origin:*
前端: ajax可解决GET/POST跨域需求

GET方式:


POST方式:


jsonp

利用script标签的src属性在引入外部JS时不受同源策略限制的特性,来实现跨域。
JSONP只能处理GET请求方式的跨域
后端:
由服务器端构建一个字符串:字符串中的内容是能够在 JS 中执行的函数调用的结构
前端:

  1. 创建 script 元素
  2. 设置 src 属性,传递 callback 参数指明全局回调函数的名称
  3. 添加到 body 中
  4. 创建全局函数,用于处理响应数据
  5. 删除 script 元素
/* jsonp ajax请求
 * @param  url  string 请求路径
 * @param  cb    string  全局函数名
 * @param  query  object  请求参数
 */
ajaxJsonp : function(url, cb, query) {
    // 1、 创建script标签
    var script  = document.createElement("script");
    // 2、拼接url和回调函数以及请求参数
    url += "?cb="+cb;
    if(query){
        for(var key in query){
            url += "&"+key+"="+query[key];
        }
    }
    
    // 3、设置script的src属性
    script.src = url;
    // 4、 把script添加到body中
    document.body.appendChild(script);
    document.body.removeChild(script);
}

promise(ES6)

承诺:—> 兑现 (resolve) 或 失信(rejected)
用于表示一个异步操作的最终状态(完成或失败),以及其返回的值。它允许你为异步操作的成功和失败分别绑定相应的处理方法。这让异步方法可以像同步方法那样返回值,但并不是立即返回最终执行结果,而是一个能代表未来出现的结果的promise对象。

一个 Promise有以下几种状态:
pending: 初始状态,既不是成功,也不是失败状态。
fulfilled: 意味着操作成功完成。
rejected: 意味着操作失败。

创建Promise对象:

var promise = new Promise( executor );
executor: 是一个函数,该函数在创建Promise对象的同时被调用执行。
executor:
语法:function(resolve, reject) {…}

  • resolve:将Promise对象状态修改为 fulfilled,可以传递参数到then方法的第一个函数中
  • reject:将Promise对象状态修改为 rejected,可以传递参数到 then 方法的第二个函数中

API:

  • Promise.prototype.then(onfulfilled, onrejected) 方法:
    – onfulfilled 绑定的是成功时执行的函数
    – onrejected 绑定的是失败时执行的函数

  • Promise.all(iterable)
    – iterable : 可迭代对象(数组)
    – 返回Promise对象
    – 当数组中所有Promise对象都完成时,回调执行成功的函数,当只要有一个执行失败时,就回调执行失败的函数。

ajaxGetPromise : function(url, query, isJson){
  return new Promise(function(resolve, reject) {
  // 拼接url加query
  if(query) {
      url += "?";
      for(var key in query){
          url += key+"="+query[key]+"&";
      }
      // 把最后一个&删掉
      url = url.slice(0, -1);
  }
  
  // 1、创建对象
  var ajax = new XMLHttpRequest();
  // 2、建立连接
  ajax.open("GET", url, true);
  
  // 3、发送请求
  ajax.send(null);
  
  // 4、监听状态的改变
  ajax.onreadystatechange = function(){
  if(ajax.readyState === 4){
      if(ajax.status === 200){
          // 用户传了回调才执行
          // isJson默认值为true,要解析json
          if(isJson === undefined){
              isJson = true;
          }
          var res = isJson ? JSON.parse(ajax.responseText) : ajax.responseText;
          resolve(res);
      }else{
          // 请求失败
          reject();
      }
  }
  }
  })
}

更多推荐

JS-ajax详解