知识点
XMLHttpRequest
网页实现ajax的最核心的api
// get请求
const xhr = new XMLHttpRequest() // new Class 初始化一个实例
xhr.open('GET', '/data/test.json', true)
//.open()传入一个”GET“方法, true为异步 false为同步,网络请求不能卡顿,所以要异步。此时不发送请求
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')
}
}
}
// get请求 不用发送任何数据
xhr.send(null) //send() 之后触发onreadystatechange函数
// post 请求
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 if (xhr.status === 404) {
console.log('404 not found')
}
}
}
const postData = {
username: 'baohaojie',
password: 'xxx'
}
xhr.send(JSON.stringify(postData))
状态码
xhr.readyState
- 0 (未初始化) 还没有调用send() 方法
- 1(载入)已调用send()方法,正在发送请求
- 2(载入完成)send()方法执行完成,已经接收到全部响应内容
- 3(交互)正在解析响应内容
- 4(完成)响应内容解析完成,可以在客户端调用(内容解析完成,其他时候都拿不到responeseText)
xhr.status
http协议的状态码
- 2xx 表示成功处理请求,如200
- 3xx 需要重定向,浏览器直接跳转,如301 302 304(永久重定向,暂时重定向,资源未改变)
- 4xx 客户端请求错误,如404(请求地址有错误,服务端没有) 403(没有权限)
- 5xx 服务端错误
跨域:同源策略,跨域解决方案
浏览器要保证安全,所以有了同源策略
什么是跨域(同源策略)
- 前端页面通过浏览器向server端发起ajax 请求时,浏览器要求当前网页和 server 必须同源(安全)
- 同源:协议(http/https)、域名(xx.xx.com)、端口(如果不写,默认80,如下server地址),三者必须一致
- 前端:http://a.com:8080; server:https://b.com/api/xxx(三者皆不同)
- 同源策略仅限于浏览器。搜索引擎的爬虫是服务端请求访问各个网站的网站接口,是从server端发起请求
加载图片 CSS JS 可无视同源策略
用法
用途
可以看pv、uv等。统计打点功能,其实就是向第三方服务发个请求,如果是ajax发请求,则出现跨域。初始化图片,把图片的地址写成第三方统计服务的地址,在地址里写上各种需要的参数,通过图片发请求,则跨域
跨域
- 所有的跨域,都必须经过 server 端允许和配合
- 未经 server 端允许就实现跨域,说明浏览器有漏洞,危险信号
JSONP
JSONP是前端实现跨域,但必须经过想要跨域的server 端 允许和配合
JSONP 实现原理
实现代码
服务端可以任意动态拼接数据返回
<script>
window.abc = function (data) {
console.log(data)
}
</script>
<script src="http://localhost:8002/jsonp.js?username=xxx&callback=abc"></script>
整个跨域过程,可以写函数把script动态插进去,将整个过程封装,一般按照如下使用
CORS(跨域资源共享 Cross-origin resource sharing 服务端设置 http header)
即response返回的时候可以设置header
如第一行服务端设置了跨域,前端直接就可以访问8011端口,不需要跨域了
题目
手写一个简易的 ajax
function ajax(url, successFn){
const xhr = new XMLHttpRequest()
xhr.open("GET",url,true)
xhr.onreadystatechange = function () {
if(xhr.readyState===4){
if(xhr.status===200){
successFn(xhr.responseText)
}
}
}
xhr.send(null)
}
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))
跨域的常用实现方式
- JSONP
- CORS
ajax的工具
面试不考,但实际过程中会使用