含义: async javascript and xml 异步的js和xml
javascript
//1、建立Ajax实例
let xhr = new XMLHttpRequest();//IE下为ActiveObject对象
//2、打开请求: 发送请求以前的一些配置项
//1.HTTP METHOD:GET/POST/PUT/DELETE/HEAD/OPTIONS/TRACE/CONNECT/
//2.url:接口地址
//3.async:设置Ajax的同步异步,默认是异步
//4.user-name/user-pass用户名和密码,通常不用
xhr.open(method, url, async, [user-name], [user-pass])
//3、事件监听:通常监听的都是readystatechange事件(Ajax状态改变事件),基于这个事件能够获取服务器返回的响应头响应主体
xhr.onreadystatechange = () => {
if(xhr.readyState === 4 && xhr.status === 200){
console.log(xhr.responseText);
}
};
//4、发送Ajax请求:从这步开始,当前Ajax任务开始,若是Ajax是同步的,后续代码不会执行,要等到Ajax状态成功后再执行
xhr.send([请求主体内容])
复制代码
GET经过url字符串传参,POST经过请求主体java
[GET]
xhr.open('GET', '/tmp/list?xxx=xxx&xxx=xxx')
[POST]
xhr.send('xxx=xxx')
(通常是url-encode格式)
复制代码
由于 GET是基于”问号传参“把信息传递给服务器的,容易被hack进行url劫持,post是基于请求主体传递的。ios
不可控:是浏览器的自主记忆,没法经过JS控制。 解决方案ajax
xhr.open('GET', `/temp/list?lx=1000&_=${Math.random()}`);
复制代码
0 => UNSENT 刚开始建立xhr, 尚未发送编程
1 => OPENED 已经执行了open这个操做json
2 => HEADERS_RESERVED 已经发送Ajax,响应头已经被客户端接受axios
3 => LOADING 响应主体内容正在返回设计模式
4 => DONE 响应主体已经被客户端接收跨域
根据状态码可以清楚的反映出当前交互的结果和缘由浏览器
1XX :指示信息-表示请求已接受、继续处理
2XX :成功 - 表示请求已被成功接收
3XX :成功,可是已经重定向
4XX : 客户端错误
5XX : 服务端错误
具体举例:
200 OK: 客户端请求成功
206 Partial Content: 客户发送了一个带有Range头的GET请求,服务器完成了它
301 Moved Permamently: 已经永久转至新的url
302 Found: 临时转至新的url,当一台服务器达到最大并发数,会转移服务器处理
304 Not Modified: 服务器告诉客户,原来的缓存能够继续使用,如CSS/JS/HTML/IMG,Ctrl+F5 304缓存失效
400 Bad Request: 客户端有语法错误,服务器不能理解
401 Unauthorized: 请求未经受权
403 Forbidden: 对被请求页面的访问被禁止
404 Not Found: 请求资源不存在
413 Request Entity Too Large 和服务器交互的内容资源超过最大大小
500 Interval Server Error 服务器错误,原来的缓存还能使用
503 Service Unavailable
xhr.response 响应主体内容
xhr.responseText 响应的内容是字符串(JSON或XML文档)
xhr.responseXML 响应的内容是xml
xhr.status 返回的HTTP状态码
xhr.statusText 状态码的描述
xhr.timeout 设置请求超时的时间
xhr.timeout = 1000
xhr.ontimeout = () => {
console.log(‘请求超时’)
}
复制代码
xhr.withCredentials 是否容许跨域(false)
xhr.abort() 强制中断Ajax请求
xhr.abort();
xhr.onabort = () => {}
复制代码
xhr.getAllResponseHeaders() 获取全部响应头信息
xhr.getResponseHeader([key])例如:xhr.getResponseHeader('date')就是获取响应头中的服务器时间
xhr.open() 打开url请求
xhr.overrideMimeType() 重写MIME类型
xhr.send()发送Ajax请求,参数为请求主体对象
xhr.setRequestHeader() 设置自定义请求头信息(不能出现中文),必须在open以后设置
//小例子
xhr.onreadystatechange = () => {
if(!/^(2|3)\d{2}$/.test(xhr.status))return;//证实服务器已经返回内容了
if(xhr.readyState === 2){
let time = xhr.getResponseHeader('date');
}
if(xhr.readyState === 4 && xhr.status === 200){
JSON.parse(xhr.responseText);
}
}
复制代码
异步:
let xhr = new XMLHttpRequest();
xhr.open('GET', 'xxx', true);
xhr.onreadystatechange = () => {
if(xhr.readyState === 2) {
console.log(1);
}
if(xhr.readyState === 4) {
console.log(2)
}
}
xhr.send();
console.log(3)
//3 1 2
复制代码
同步:
let xhr = new XMLHttpRequest();
xhr.open('GET', 'xxx', false);
xhr.onreadystatechange = () => {
if(xhr.readyState === 2) {
console.log(1);
}
if(xhr.readyState === 4) {
console.log(2)
}
}
xhr.send(); //任务开始,只要当前Ajax请求这件事没完成(readyState没到4),什么都不能作
console.log(3)
//2 3 为何呢?
//因为是同步编程,主任务队列在状态没有变成4以前一直被Ajax请求占用,其余事件作不了。
//因此,只有readyState变成4才能执行方法。
let xhr = new XMLHttpRequest();
xhr.open('GET', 'xxx', false);
xhr.send(); //任务开始,只要当前Ajax请求这件事没完成(readyState没到4),什么都不能作
//如今状态已经为4
xhr.onreadystatechange = () => {
if(xhr.readyState === 2) {
console.log(1);
}
if(xhr.readyState === 4) {
console.log(2)
}
}
console.log(3)
//3
//所以采用异步Ajax
复制代码
/** * DATA: * 若是是GET请求是基于问号传参过去的 * 若是是POST请求是基于请求主体传递过去的 * data的值能够是对象也能够是字符串(通常经常使用对象): * 若是是对象,jq会把对象转换为 xxx=xxx 的模式(x-www-form-urlencoded) * DATA-TYPE:预设置获取结果的数据格式 TEXT/JSON/JSONP/HTML/XML/SCRIPT(服务器返回给客户端的响应主体中的内容通常是字符串, * 而设置DATA-TYPE='json',jq会内部把获取的字符串转化为JSON格式的对象 => 它不影响服务器返回的结果,只是二次处理结果) * ASYNC:设置是否异步 * CACHE:设置是否缓存,当设置FALSE,而且get请求,JQ会在请求的url地址末尾加随机数 * SUCCESS:回调函数,当Ajax请求成功执行,JQ执行回调函数时把响应主体中获取的结果(二次处理)当作参数 * ERROR: 请求失败后执行的回调函数 */
$.ajax({
url: 'xxx',
method: 'GET',
data: null,
dataType: 'json',
async: true,
cache: true,
success: (result, textStatus, xhr) => {},
error: () => {}
})
复制代码
~ function (window) {
function AJAX(options) {
return new AJAX.prototype.init(options);
}
function init(options = {}){
let {
url,
method = 'GET',
data = null,
dataType = 'JSON',
async = true,
cache = true,
success,
error
} = options;
//=>MOUNT 把配置项挂载到实例上
['url', 'method', 'data', 'dataType', 'async', 'cache', 'success',
'error'].forEach(item => {
this[item] = eval(item);
});
}
AJAX.prototype = {
constructor: AJAX,
init,
sendAjax(){
this.handleCache();
this.handleData();
//send
let {method, url, async, error, success} = this;
//SEND发送请求
let xhr = new XMLHttpRequest();
xhr.open(method, url, async);
xhr.onreadystatechange = () => {
if(xhr.readyState === 4){
if(!/^(2|3)\d{2}$/.test(xhr.status)){
error && error(xhr.statusText, xhr)
}
//处理DATA-TYPE
let result = this.handleDataType(xhr);
success && success(result, xhr);
}
};
xhr.send();
},
handleDataType(xhr) {
let dataType = this.dataType.toUpperCase(),
result = xhr.responseText;
switch (dataType) {
case 'TEXT':
break;
case 'JSON':
result = JSON.parse(result);
break;
case 'XML':
result = xhr.responseXML;
break;
}
return result;
},
handleCache() {
let {url, method, cache} = this;
if(/^GET$/i.test(method) && cache==false){
url += `${this.check()}=${+(new Date())}`;
}
},
handleData() {
let {data, method} = this;
if(!data) return;
if(typeof data === 'object'){
//若是是一个对象,咱们把它转换为x-www-form-urlencoeded模式
for(let key in data){
if(data.hasOwnProperty(key)){
str += `${key}=${data[key]}`;
}
}
data=str.substring(0,str.length);
}
if(/^(GET|DELETE|HEAD|TRACE|OPTIONS)$/i.test(method)){
this.url += `${this.check()}${data}`;
this.data = null;
return;
}
this.data = data; //POST处理方式
},
check() {
return this.url.indexOf('?')>-1?'&':'?';
}
}
init.prototype = AJAX.prototype;
window.ajax = AJAX;
}(window)
复制代码
~ function (window) {
//设置默认的参数配置项
let _default = {
method: 'GET',
url: '',
baseURL: '',
headers: {},
dataType: 'JSON',
data: null, //POST系列
params: null, //GET系列
cache: true
};
//基于Promise设计模式管理Ajax
let ajaxPromise = function axios() {
let {
url,
baseURL,
data,
dataType,
headers,
cache,
params
} = options;
//=>把传递的参数进一步进行处理
if(/^(GET|DELETE|HEAD|OPTIONS)$/.test(method)){
//GET参数
if(params) {
url += `${ajaxPromise.check(url)}${ajaxPromise.formatData(params)}`
}
if(cache === false){
url += `${ajaxPromise.check(url)}_=${+(new Date())}`
}
data= null;//GET系列请求主体为空
}else{
//POST系列
if(data){
data = ajaxPromise.formatData(data);
}
}
//=>基于Promise发送Ajax
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest();
xhr.open(method, `${baseURL}${url}`);
if(headers != null && typeof headers === 'object'){
for(let attr in headers){
if(headers.hasOwnProperty(attr)){
let val = headers[attr];
if(/[\u4e00-\u9fa5]/.test(val)){
val = encodeURIComponent(val);
}
xhr.setRequestHeader(attr, headers[attr]);
}
}
}
//=>若是headers存在,咱们须要设置请求头
xhr.onreadystatechange = () => {
if (xhr.readyState === 4){
if(/^(2|3)\d{2}$/.test(xhr.status)){
let result = xhr.responseText;
dataType = dataType.toUpperCase();
dataType === 'JSON'?result = JSON.parse(result):(dataType === 'XML'?result = xhr.responseXML : null);
resolve(result, xhr);
return;
}
reject(xhr.statusText, xhr);
}
}
xhr.send(data);
})
}
ajaxPromise.defaults = _default;
ajaxPromise.formatData = function formatData(){
let str = ``;
for(let attr in obj) {
if(obj.hasOwnProperty(attr)){
str += `${attr}=${obj[attr]}&`;
}
return str.substring(0, str.length-1)
}
}
ajaxPromise.check = function check(url){
return url.indexOf('?')>-1?'&':'?';
}
//GET系列
['get', 'delete', 'head', 'options'].forEach(item => {
ajaxPromise[item] = (url, options = {}) => {
options = {
..._default,
...options,
url,
method: item.toUpperCase()
};
return ajaxPromise(options);
}
})
//POST系列
['post', 'put', 'patch'].forEach(item => {
ajaxPromise[item] = (url, data = {}, options = {}) => {
options = {
..._default,
...options,
url,
method: item.toUpperCase(),
data
};
return ajaxPromise(options);
}
})
window.ajaxPromise = ajaxPromise;
}(window)
复制代码
关于Ajax一点小小的总结,但愿对你们有帮助!