1. 创建Ajax
let xhr = null;
if(window.XMLHttpRequest){
//大多数浏览器
xhr = new XMLHttpRequest();
}else{
//古董级浏览器
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
if(xhr != null){
xhr.open('GET', 'data/test.json', true); // true表示异步
xhr.onreadystatechange = function () {
if(xhr.readyState === 4){
if(xhr.status === 200){
alert(xhr.responseText);
} else {
alert("Problem retrieving XML data");
}
}
}
xhr.send(null);
} else {
alert("Your browser does not support XMLHTTP.");
}
//POST请求
xhr.open('POST', '/login', true);
const postData = {
userName: 'zhangsan',
password: 'xxx'
}
xhr.send(JSON.stringify(postData));
2. xhr.readyState
- 0 - (未初始化) 还没有调用send()方法
- 1 - (载入) 已调用send()方法,正在发送请求
- 2 - (载入完成) send()方法执行完成,已经接收到全部响应内容
- 3 - (交互) 正在解析响应内容
- 4 - (完成) 响应内容解析完成,可以在客户端调用
3. xhr.status
- 2xx - 表示成功处理请求,如200
- 3xx - 需要重定向,浏览器直接跳转,如301,302,304
- 4xx - 客户端请求错误,如404,403
- 5xx - 服务器端错误
4. 同源策略
ajax请求时,浏览器要求当前网页和server必须同源(安全)
同源: 协议,域名,端口,三者必须一致
可无视同源策略的情况: 图片、css、js,如下:
<img src=跨域的图片地址 /> // 可用于统计打点,可使用第三方统计服务
<link href=跨域的图片地址 /> // 可使用CDN,CDN一般都是外域
<script src=跨域的图片地址 ></script> //可实现JSONP
- 所有的跨域,都必须经过server端允许和配合
- 未经server端允许就实现跨域,说明浏览器有漏洞,危险信号
5. JSONP
什么是JSONP?
JSONP是JSON with padding(填充式JSON)的简写,是应用JSON的一种新方法,是被包含在函数调用中的JSON,由两部分组成:回调函数和数据。
JSONP原理
- 首先是利用script标签的src属性来实现跨域。
- 通过将前端方法作为参数传递到服务端,然后由服务的注入参数之后再返回,实现服务器向客户端通信。
- 由于使用script标签的src属性,因此只支持get方法。
JSONP实现
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript">
// 得到航班信息查询结果后的回调函数
var flightHandler = function(data){
alert('你查询的航班结果是:票价 ' + data.price + ' 元,' + '余票 ' + data.tickets + ' 张。');
};
// 提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码)
var url = "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler";
// 创建script标签,设置其属性
var script = document.createElement('script');
script.setAttribute('src', url);
// 把script标签加入head,此时调用开始
document.getElementsByTagName('head')[0].appendChild(script);
</script>
</head>
<body>
</body>
</html>
// 服务端
flightHandler({
"code": "CA1998",
"price": 1780,
"tickets": 5
});
6. 手写ajax
function ajax(url){
const p = new Promise((resolve, reject) => {
const xhr = new XMLHttPRequest();
xhr.open('GET', 'url, true);
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status === 200){
resolve(JSON.parse(xhr.responseText));
}
else if(xhr.status === 404){
reject(new Error('404 not found!'));
}
}
}
xhr.send(null);
})
return p;
}
// 调用
const url = '/data/test.json';
ajax(url)
.then(res => {
console.log(res);
})
.catch(err => {
console.error(err);
})