ajax 的核心API – XMLHttpRequest
get 请求
// 新建 XMLHttpRequest 对象的实例
const xhr = new XMLHttpRequest();
// 发起 get 请求,open 的三个参数为:请求类型,请求地址,是否异步请求( true 为异步,false 为同步)
xhr.open("GET", "/data/test.json", false);// 定义 xhr 状态改变的处理函数
xhr.onreadystatechange = function () {// xhr 的 readyState 属性变为 4if (xhr.readyState === 4) {// 网络请求返回的状态码为 200if (xhr.status === 200) {alert(xhr.responseText);} else if (xhr.status === 404) {// 网络请求返回的状态码为 404console.log("404 not found");} else {console.log("其他情况");}}
};// 发出请求,会触发 xhr 状态的改变
xhr.send(null);
post 请求
// 新建 XMLHttpRequest 对象的实例
const xhr = new XMLHttpRequest();
// open 的三个参数为:请求类型,请求地址,是否异步请求( true 为异步,false 为同步)
xhr.open("POST", "/login", false);// 定义 xhr 状态改变的处理函数
xhr.onreadystatechange = function () {// xhr 的 readyState 属性变为 4if (xhr.readyState === 4) {// 网络请求返回的状态码为 200if (xhr.status === 200) {alert(xhr.responseText);} else if (xhr.status === 404) {// 网络请求返回的状态码为 404console.log("404 not found");} else {console.log("其他情况");}}
};// 定义 post 请求的参数
const postData = {userName: "朝阳",password: "xxx",
};// 发出请求 -- 参数需转为字符串
xhr.send(JSON.stringify(postData));
XMLHttpRequest 的 readyState 属性
- 0 —— UNSET 尚未调用 open方法
- 1 —— OPENED open 方法已被调用
- 2 —— HEADERS RECEIVED send 方法已被调用,header 已被接收
- 3 —— LOADING 下载中,responseText已有部分内容
- 4 —— DONE 下载完成
XMLHttpRequest 的 status 属性
即 http 请求的状态码,详见
https://blog.csdn.net/weixin_41192489/article/details/136446539
同源策略
ajax 请求地址的 协议、域名、端口 必须和当前网页的地址相同!
- 浏览器中的 ajax 请求才有同源策略限制
- 图片、css文件、js文件的加载,没有同源策略限制,应用如下:
- 图片用于使用第三方统计服务完成统计打点(如统计网页浏览量)
- 使用 CDN 加速图片、css文件、js文件
<script>
可用于实现 JSONP
跨域
所有的跨域,都必须经过 server 端允许和配合
【考题】哪些 html标签能绕过跨域 ?
<a>
标签的href属性可以实现跨域链接,但是只能用于GET请求
<a href="http://baidu.com">跨域链接</a>
<img>
标签的src属性可以加载跨域图片
<img src="http://**.jpg" alt="跨域图片">
<link>
标签的href属性可以加载跨域样式表。
<link rel="stylesheet" href="http://**.cn/styles.css">
<script>
标签的src属性可以加载跨域脚本文件,常用于JSONP跨域请求。
<script src="http://**.cn/api.js"></script>
以上标签和属性只是在特定情况下可以用于跨域请求,具体是否允许跨域请求还要看服务器端是否设置了相应的CORS(跨域资源共享)策略。如果服务器没有设置CORS策略,浏览器会阻止跨域请求。
方案一 JSONP
JSONP 实现跨域的过程:借助 script 标签没有同源策略限制的特点,向跨域的目标服务器加载到需要的数据。
范例:
<script>window.callback= function (data) {console.log(data)}</script><script src="http://localhost:8008/jsonp.js"></script>
jsonp.js
callback({ name: '朝阳' }
)
借助 script 标签 向目标服务器加载到 jsonp.js 文件,执行 callback 函数,因本地已定义了 callback 函数,便会触发本地 js 代码的执行,获取到 jsonp.js 文件中的数据,从而实现了跨域。
jQuery 实现 jsonp
jQuery 内实现 jsonp 的方式与范例中相同,只是进行了封装。
方案二 跨域资源共享 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))
【考题】怎么实现跨域?
- JSONP
- CORS
实战中实现 ajax 的常用插件
- jQuery
- fetch —— 新增的 Web API
- axios