补充上章:
实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信
1. 对于简单请求,浏览器直接发出CORS请求。具体来说,就是在头信息之中,增加一个Origin
字段。
2. 如果Origin
指定的源,不在许可范围内,服务器会返回一个正常的HTTP回应。浏览器发现,这个回应的头信息没有包含Access-Control-Allow-Origin
字段(详见下文),就知道出错了,从而抛出一个错误,被XMLHttpRequest
的onerror
回调函数捕获。
3. 如果Origin
指定的域名在许可范围内,服务器返回的响应,会多出几个头信息字段。
非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。
浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest
请求,否则就报错。
因为回调地狱的产生:执行一个ajax请求时用onreadystatechange事件,而现在要执行另一个ajax请求(但是要从上一个ajax请求中或去参数),在第二个ajax请求还没完时又要进行第三个ajax请求….一直往下
而promise将数据请求和数据处理区分开来。
Promise对象的三种状态:
pending: 等待中,或者进行中,表示还没有得到结果
resolved(Fulfilled): 已经完成,表示得到了我们想要的结果,可以继续往下执行
rejected: 也表示得到结果,但是由于结果并非我们所愿,因此拒绝执行
new Promise(function(resolve, reject) {
if(true) { resolve() };
if(false) { reject() };
})
先由本来函数确定resolve还是reject;resolve执行then部分,否则执行catch部分(then的第二个参数部分)
function fn(num) {
return new Promise(function(resolve, reject){
if (typeof num == 'number') {
resolve();
}
else
{
reject();
}
}) .then(function(){
alert('参数是一个number值');
})
.then(null, function() {
alert('参数不是一个number值');
})
}
fn('hehe');
fn(1234);
上下两个是相同的效果:
function fn(num) {
return new Promise(function(resolve, reject){
if (typeof num == 'number') {
resolve();
}
else
{
reject();
}
})
}
fn('hehe').then(function(){
alert('参数是一个number值')}).then(null,function() {
alert('参数不是一个number值');
});
function want() {
alert('这是你想要执行的代码');
}
function fn(want) {
alert('这里表示执行了一大堆各种代码');
// 返回Promise对象
return new Promise(function(resolve, reject) {
if (typeof want == 'function') {
resolve(want);
} else {
reject('TypeError: '+ want +'不是一个函数')
}
})
}
fn(want).then(function(want) { want(); })
fn('1234').catch(function(err) {
alert(err);
})
一个简单的封装,正确的返回结果,就resolve一下,错误的返回结果,就reject一下。
var url = '';
// 封装一个get请求的方法
function getJSON(url) {
return new Promise(function(resolve, reject) {
var XHR = new XMLHttpRequest();
XHR.open('GET', url, true);
XHR.send();
XHR.onreadystatechange = function() {
if (XHR.readyState == 4) {
if (XHR.status == 200) {
try { var response = JSON.parse(XHR.responseText);
resolve(response);
}
catch (e) {
reject(e);
}
} else {
reject(new Error(XHR.statusText));
} } } }) }
getJSON(url).then(resp => console.log(resp));
Function renderAll() {
return Promise.all([getJSON(url), getJSON(url1)]);
}
renderAll().then(function(value) {
alert (value); //首先两个都resolve后调用then方法,value是两个promise对象
})
与Promise.all相似的是,Promise.race都是以一个Promise对象组成的数组作为参数,不同的是,只要当数组中的其中一个Promsie状态变成resolved或者rejected时,就可以调用.then方法了。
Function renderAll() {
return Promise.race([getJSON(url), getJSON(url1)]);
}
renderAll().then(function(value) {
alert (value);
})