html模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>ajax 演示</title>
</head>
<body>
<p>一段文字 1</p>
<script src="./ajax.js"></script>
</body>
</html>
/data/test.json
{
"name": "zhangsan"
}
手写XMLHttpRequest
xhr.readyState
- 0 - (未初始化)还没有调用send()方法
- 1 - (载入)已调用send()方法,正在发送请求
- 2 - (载入完成)send()方法执行完成,已经接收到全部响应内容
- 3 - (交互)正在解析响应内容
- 4 - (完成)响应内容解析完成,可以在客户端调用
xhr.status
- 2xx - 表示成功处理请求,如200
- 3xx - 需要重定向,浏览器直接跳转,如301(永久重定向),302(临时重定向),304(资源未改变,使用缓存)
- 4xx - 客户端请求错误,如404,403
- 5xx - 服务器端错误
const xhr = new XMLHttpRequest()
xhr.open('GET', '/data/test.json', true) //设置true为异步请求
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
console.log(
JSON.parse(xhr.responseText)
)
alert(xhr.responseText)
} else if (xhr.status === 404) {
console.log('404 not found')
}
}
}
xhr.send(null)
跨域
同源策略
- ajax请求时,浏览器要求当前网页和server必须同源(安全)
- 同源:协议、域名、端口,三者必须一致
- 前端:http://a.com:8080/ ; server:https://b.com/api/xxx(协议、域名、端口均不相同)
img、css、js可无视同源策略
- <img />可用于统计打点,使用第三方统计服务
- <link /><script>可使用CDN,CDN一般都是外域
<script>可实现JSONP
JSONP
- script 可绕过跨域限制
- 服务器可以任意拼接数据返回
- 所以,script就可以获得跨域的数据,只要服务端愿意返回
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>jsonp 演示</title>
</head>
<body>
<p>一段文字 1</p>
<script>
window.abc = function (data) {
console.log(data)
}
</script>
<script src="http://localhost:8002/jsonp.js?username=xxx&callback=abc"></script>
</body>
</html>
//jsonp.js
abc(
{ name: 'xxx' }
)
CORS - 服务器设置http header
手写一个简易的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))
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。