目录
知识点
- XMLHttpRequest
- 状态码
- 跨域:同源策略,跨域解决方案
一、XMLHttpRequest
const xhr = new XMLHttpRequest()
xhr.open(“GET, ”/test.json”, true) // true异步请求
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
alert(xhr.responseText)
} else if (xhr.status === 404) {
console.log('404 not found')
}
}
}
xhr.send(null)
1. Xhr.readyState 状态码
0-(未初始化)还没有调用send()方法
1-(载入)已经调用send()方法,正在发送请求
2-(载入完成)send()方法执行完成,已经接收到全部响应内容
3-(交互)正在解析响应内容
4-(完成)响应内容解析完成,可以在客户端调用(可以拿到responseText)
2. Xhr.status状态码(http协议)
2xx - 表示成功处理请求,如200
3xx - 需要重定向,浏览器直接跳转,如301(永久重定向) 302(临时重定向) 304(资源未改变)
4xx - 客户端请求错误,如404(请求地址有误) 403(客户端没有权限)
5xx - 服务器端有误
二、跨域
1. 什么是跨域(同源策略)
Ajax请求时,浏览器要求当前网页和server必须同源(安全)
同源:协议、域名、端口,三者必须一致
(例子:前端:http://a.com:8080/ server: https://b.com/api/xxx )
加载图片css js 可以无视同源策略
<img src= 跨域的图片地址 />
<link href=跨域的css地址 />
<script src= 跨域的js地址></script>
<img /> 可用于统计打点,可以使用第三方统计服务
<link /> <script> 可以使用CDN,CDN一般都是外域
<script> 可以实现JSONP
所有的跨域,都必须经过server端允许和配合
未经server端允许就实现跨域,说明浏览器有漏洞,危险信号
2. JSONP
访问https://imooc.com/,服务器端一定返回一个HTML文件吗?不一定
服务器端可以任意动态拼接数据返回,只要符合html格式要求
<script>可以绕过跨域限制
服务器可以任意动态拼接数据返回
所以,<script>就可以获得跨域的数据,只要服务器端愿意返回拼接数据
<script>
window.callback = function(data){
console.log(data);
}
</script>
<script src="http://localhost:8002/jsonp.js"></script>
<script src="http://localhost:8002/jsonp.js?username=xxx&callback=abc"></script>
jsonp.js
callback(name:'zhangsan')
jQuery实现jsonp
$.ajax({
url: 'http://localhost:8002/x-origin.json',
dataTtype: 'jsonp', // 发送ajax请求
jsonpCallback: 'callback', // 函数名
success : function(data) {
console.log(data)
}
})
为了便于客户端使用数据,逐渐形成了一种非正式传输协议,人们把它称作JSONP,该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。
ajax 的核心是通过 XmlHttpRequest 获取非本页内容,而 jsonp 的核心则是动态添加 <script> 标签来调用服务器提供的 js 脚本。
参考链接:透彻理解JSONP原理
JSONP的原理:ajax 请求受同源策略影响,不允许进行跨域请求,而 script 标签 src 属性中的链接却可以访问跨域的js脚本,利用这个特性,服务端不再返回JSON格式的数据,而是返回一段调用某个函数的js代码,在src中进行了调用,这样实现了跨域。
3. CORS
CORS:全称"跨域资源共享"(Cross-origin resource sharing)。
CORS需要浏览器和服务器同时支持,才可以实现跨域请求。CORS的整个过程都由浏览器自动完成,前端无需做任何设置,跟平时发送ajax请求并无差异。因此,实现CORS的关键在于服务器,只要服务器实现CORS接口,就可以实现跨域通信。
对于前端来说无需做任何配置,与发送普通ajax请求无异。唯一需要注意的是,需要携带cookie信息时,需要将withCredentials设置为true即可。CORS的配置,完全在后端设置,配置起来也比较容易,目前对于大部分浏览器兼容性也比较好。CORS优势也比较明显,可以实现任何类型的请求,相较于JSONP跨域只能使用get请求来说,也更加便于我们使用。
参考链接:CORS原理及详细使用
三、ajax常用插件
1. 使用jQuery实现ajax
2. fetch
3. axios
四、问题解答
1. 手写简单的Ajax
// 使用promise实现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 || xhr.status === 500) {
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))
2. 跨域以及解决方法
(1)JSONP ajax 请求受同源策略影响,不允许进行跨域请求,而 script 标签 src 属性中的链接却可以访问跨域的js脚本,利用这个特性,服务端不再返回JSON格式的数据,而是返回一段调用某个函数的js代码,在src中进行了调用,这样实现了跨域。
(2)CORS 全称"跨域资源共享"(Cross-origin resource sharing)。CORS的整个过程都由浏览器自动完成,前端无需做任何设置。