JS-Web-API(三)- Ajax
# 1.几道面试题(以点带面)
- 手写一个简易的 ajax
- 跨域的常用实现方式
# 2.涉及知识点
- XMLHttpRequest
- 状态码
- 跨域:同源策略,跨域解决方案
# 2.1 XMLHttpRequest
使用示例demo
const xhr = new XMLHttpRequest()
xhr.open('POST','/login',true)
xhr.onreadystatechange = function{
if (xhr.readyState === 4) {
if (xhr. status === 200) {
// console.log(
// JSON.parse(xhr.responseText)
// )
alert(xhr.responseText)
} else {
console.log('其他情况')
}
}
}
const postData = {
userName:'zhangsan',
password: 'xxx'
}
xhr.send(JSON.stringify(postData))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 2.2 xhr.readyState
- 数值为0-(未初始化)还没有调用send()方法
- 数值为1-(载入)已调用send()方法,正在发送请求
- 数值为2-(载入完成)send()方法执行完成,已经接收到全部响应内容
- 数值为3-(交互)正在解析响应内容
- 数值为4-(完成)响应内容解析完成,可以在客户端调用
# 2.3 xhr.status
- 2xx-表示成功处理请求,如200
- 3xx-需要重定向,浏览器直接跳转,如301,302,304
- 4xx-客户端请求错误,如404,403
- 5xx-服务器端错误
# 2.4 跨域
- 什么是跨域(同源策略)
- JSONP
- CORS(服务端支持)
# 同源策略
- ajax请求时,浏览器要求当前网页和server必须同源(安全)
- 同源:协议、域名、端口,三者必须一致
# 加载图片、css、js 可无视同源策略
<img src=跨域的图片地址/>
(注意图片在server端可能会做防盗链处理)<link href=跨域的css地址/>
<script src=跨域的js地址></script>
# 标签跨域常见用途
<img/>
可用于统计打点,可使用第三方统计服务<link/>
、<script>
可使用CDN,CDN一般都是外域<script>
可实现 JSONP
# 跨域前提
- 所有的跨域,都必须经过 server 端允许和配合
- 未经server端允许就实现跨域,说明浏览器有漏洞,危险信号
# JSONP
- 访问
https://xxx.com/
,服务端一定返回一个html文件吗? - 答案是不一定,服务器可以任意动态拼接数据返回,只要符合html格式要求
- 同理于
<script src="https://xxx.com/xx.js">
,服务器返回的不一定是静态的js文件,而是可以任意动态拼接符合js格式要求的数据返回,只要能执行不报错即可 - 所以
<script>
标签就可以获得跨域的数据,只要服务器端愿意返回
示例demo
<script>
window.callback = function (data) {
//这是我们跨域得到的信息
console.log(data)
}
</script>
<script src="https://xxx.com/getData.js"></script>
<!--将返回 callback({ x: 100,y:200})-->
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
jQuery使用jsonp的例子
$.ajax({
url:'http://localhost:8882/x-origin.json',
dataType: 'jsonp' ,//jsonp用的是script标签实现,和Ajax不同,所以得告诉jQuery数据类型是jsonp
jsonpCallback:'callback',//这里传入的是回调函数的名称,服务端动态拼接要用
success: function (data){
console.log(data)
}
})
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# CORS - 服务器设置http header
//第二个参数填写允许跨域的域名称,不建议直接写"*"
response.setHeader("Access-Control-Allow-0rigin","http://localhost:8011");
response.setHeader("Access-Control-Allow-Headers","X-Requested-With");
response.setHeader("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
//接收跨域的cookie
response.setHeader"Access-Control-Allow-Credentials","true");
1
2
3
4
5
6
2
3
4
5
6
# 3.对前文问题的解答
# 3.1 手写一个简易的 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
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
使用该封装好的函数demo
const url ='/data/test.json'
ajax(url)
.then(res => console.log(res))
.catch(err=> console.error(err))
1
2
3
4
2
3
4
# 3.2 跨域的常用实现方式
- JSONP
- CORS