AJAX笔记
1、AJAX即“Asynchronous JavaScript and XML”(异步的JavaScript与XML技术)。
AJAX的核心是XMLHttpRequest,完整的ajax请求过程:
JSON是存储和交换文本信息的语法,类似XML。它采用键值对的方式来组织,易于人们阅读和编写,同时也易于机器解析和生成。
JSON是独立于语言的,也就是说不管什么语言,都可以解析JSON,只需要按照JSON的规则来就行。
JSON的长度和xml格式比起来很短小,JSON的读写速度更快;
JSON可以使用javascript内建的方法直接进行解析,转换成javascript对象,非常方便。
2、JSONP:
由于浏览器同源策略,当协议、子域名、主域名、端口号中的任意一个不相同时,都算作不同域。不同域之间相互请求资源,就算做跨域。Javascript出于安全方面的考虑,不允许跨域调用其他页面的对象。jsonp可用于解决主流浏览器的跨域数据访问的问题。
当跨域请求时,一般都会看到这个错误: XMLHttpRequest cannot load http://xxx.com/xx/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.
script
标签可以跨域请求的特性,由其 src
属性发送请求到服务器,服务器返回 JavaScript
代码,浏览器接受响应,然后就直接执行了,这和通过 script
标签引用外部文件的原理是一样的。回调函数
和数据
,回调函数一般是在浏览器控制,作为参数发往服务器端(当然,你也可以固定回调函数的名字,但客户端和服务器端的名称一定要一致)。当服务器响应时,服务器端就会把该函数和数据拼成字符串返回。 - 请求阶段:浏览器创建一个
script
标签,并给其src
赋值(类似http://example.com/api/?callback=jsonpCallback
)。 - 发送请求:当给
script
的src
赋值时,浏览器就会发起一个请求。 - 数据响应:服务端将要返回的
数据
作为参数和函数名称
拼接在一起(格式类似”jsonpCallback({name: 'abc'})
”)返回。当浏览器接收到了响应数据,由于发起请求的是script
,所以相当于直接调用jsonpCallback
方法,并且传入了一个参数。
script
标签的 src
属性只在第一次设置的时候起作用,导致 script
标签没法重用,所以每次完成操作之后要移除;function ajax(params) { params = params || {}; params.data = params.data || {}; var json = params.jsonp ? jsonp(params) : json(params); // ajax请求 function json(params) { params.type = (params.type || 'GET').toUpperCase(); params.data = formatParams(params.data); var xhr = null; // 实例化XMLHttpRequest对象 if(window.XMLHttpRequest) { xhr = new XMLHttpRequest(); } else { // IE6及其以下版本 xhr = new ActiveXObjcet('Microsoft.XMLHTTP'); }; // 监听事件 xhr.onreadystatechange = function() { if(xhr.readyState == 4) { var status = xhr.status; if(status >= 200 && status < 300) { var response = ''; var type = xhr.getResponseHeader('Content-type'); if(type.indexOf('xml') !== -1 && xhr.responseXML) { response = xhr.responseXML; //Document对象响应 } else if(type === 'application/json') { response = JSON.parse(xhr.responseText); //JSON响应 } else { response = xhr.responseText; //字符串响应 }; params.success && params.success(response); } else { params.error && params.error(status); } } }; // 连接和传输数据 if(params.type == 'GET') { xhr.open(params.type, params.url + '?' + params.data, true); xhr.send(null); } else { xhr.open(params.type, params.url, true); //设置提交时的内容类型 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); xhr.send(params.data); } } // jsonp请求 function jsonp(params) { //创建script标签并加入到页面中 var callbackName = params.jsonp; var head = document.getElementsByTagName('head')[0]; // 设置传递给后台的回调参数名 params.data['callback'] = callbackName; var data = formatParams(params.data); var script = document.createElement('script'); head.appendChild(script); //创建jsonp回调函数 window[callbackName] = function(json) { head.removeChild(script); clearTimeout(script.timer); window[callbackName] = null; params.success && params.success(json); }; //发送请求 script.src = params.url + '?' + data; //超时处理 if(params.time) { script.timer = setTimeout(function() { window[callbackName] = null; head.removeChild(script); params.error && params.error({ message: '超时' }); }, time); } }; //格式化参数 function formatParams(data) { var arr = []; for(var name in data) { arr.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name])); }; // 添加一个随机数,防止缓存 arr.push('v=' + random()); return arr.join('&'); } // 获取随机数 function random() { return Math.floor(Math.random() * 10000 + 500); } }
模拟请求
ajax({ url: 'test.php', type: 'GET', data: {'intro': 'get请求'}, success:function(res){ res = JSON.parse(res); document.getElementById('a').innerHTML = res.intro; console.log(res); } }); ajax({ url: 'test.php', type: 'POST', data: {'intro': 'post请求'}, success:function(res){ res = JSON.parse(res); document.getElementById('b').innerHTML = res.intro; console.log(res); } }); ajax({ url: 'test.php', jsonp: 'jsonpCallback', data: {'intro': 'jsonp请求'}, success:function(res){ document.getElementById('c').innerHTML = res.intro; console.log(res); } });
4、jquery.ajax()参数
从 jQuery 1.5 开始,$.ajax()
返回的jqXHR对象 实现了 Promise 接口, 使它拥有了 Promise 的所有属性,方法和行为。为了让回调函数的名字统一,便于在$.ajax()
中使用。jqXHR也提供.error()
.success()
和.complete()
方法。
//之前写法 $.ajax({ ... error:function(jqXHR, textStatus, errorThrown) {}, ... })
//promise写法 jqXHR.fail(function(jqXHR, textStatus, errorThrown) {});
主要有4个属性:
- readyState :当前状态,0-未初始化,1-正在载入,2-已经载入,3-数据进行交互,4-完成。
- status :返回的HTTP状态码,比如常见的404,500等错误代码。
- statusText :对应状态码的错误信息,比如404错误信息是not found,500是Internal Server Error。
- responseText :服务器响应返回的文本信息
第二个参数 textStatus(String 字符串):返回的是字符串类型,表示返回的状态,根据服务器不同的错误可能返回下面这些信息:
- “timeout”(超时)
- “error”(错误)
- “abort”(中止)
- “parsererror”(解析错误)
- 或者返回空值
第三个参数 errorThrown(String 字符串):也是字符串类型,表示服务器抛出返回的错误信息,如果产生的是HTTP错误,那么返回的信息就是HTTP状态码对应的错误信息,比如404的Not Found,500错误的Internal Server Error。
var _ajax = $.ajax({ url: '/AJAX请求的URL', data: {} }); _ajax.done(function (data, textStatus, jqXHR) { //success }); _ajax.fail(function (jqXHR, textStatus, errorThrown) { });