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 属性变为 4 if (xhr.readyState === 4) { // 网络请求返回的状态码为 200 if (xhr.status === 200) { alert(xhr.responseText); } else if (xhr.status === 404) { // 网络请求返回的状态码为 404 console.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 属性变为 4 if (xhr.readyState === 4) { // 网络请求返回的状态码为 200 if (xhr.status === 200) { alert(xhr.responseText); } else if (xhr.status === 404) { // 网络请求返回的状态码为 404 console.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