一、初始跨域
1.跨域是什么
- 向一个域发送请求,如果要请求的域和当前域是不同域,就叫跨域。
- 不同域之间的请求,就是跨域请求。
//const url = './index.html';
const url = 'https://www.baidu.com';//不同域
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState != 4) return;
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
console.log(xhr.responseText);
}
};
xhr.open('GET', url, true);
xhr.send(null);
呀呀,报错了
2. 什么是不同域,什么是同域
https(协议)://www.imooc.com(域名):443(端口号)/course/list(路径)
- 协议、域名、端口号,任何一个不一样就是不同域
- 与路径无关,路径不一样无所谓
3.跨域请求为什么会被阻止
- 同源策略----阻止跨域请求,其实就是浏览器本身的一种安全策略。
- 其他客户端或者服务器都不存在跨域被阻止的问题。
二、跨域解决方案
推荐优先使用
CORS
跨域资源共享,如果浏览器不支持CORS
的话,再使用JSONP
1.CORS 跨域资源共享
1. CORS 是什么
const url = 'https://www.imooc.com/api/http/search/suggest?words=js';
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState != 4) return;
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
console.log(xhr.responseText);
}
};
xhr.open('GET', url, true);
xhr.send(null);
浏览器输出结果如下:
上面案例的url也是在不同域下,但是却可以实现跨域,那么CORS
是如何工作的呢?我们来看服务器返回过来的响应头
Access-Control-Allow-Origin
这是服务器发来的请求头字段。
Access-Control-Allow-Origin: *
表明允许所有的域名来跨域请求它,*
是通配符,没有任何限制。
Access-Control-Allow-Origin: http://127.0.0.1:8080
表明只允许特定域名的跨域请求。
2. 使用CORS跨域的过程
- 浏览器发送请求
- 后端在响应头中添加
Access-Control-Allow-Origin
头信息 - 浏览器接收到响应
- 如果是同域请求,前后端通信圆满完成
- 如果是跨域请求,浏览器会从响应头中查找是否允许跨域访问
- 如果允许跨域,通信圆满完成
- 如果没找到或不包含想要跨域的域名,就丢弃响应结果
3. CORS的兼容性
- IE10及以上版本的浏览器可以正常使用
CORS
推荐一个网站可以查找各工具在浏览器的兼容情况:https://caniuse.com/
2.JSONP
1. JSONP的原理
script
标签跨域不会被浏览器阻止JSONP
主要就是利用script
标签,加载跨域文件
2. 使用JSONP实现跨域
1. 手动加载JSONP
接口
- 使用服务器准备好JSONP接口:https://www.imooc.com/api/http/jsonp?callback=handleResponse
- 打开上面的
JSONP
接口,发现是一个函数引用参数,我们可以通过改变接口参数,从而改变函数名
<script src="https://www.imooc.com/api/http/jsonp?callback=handleResponse"></script>
<!-- 相当于 -->
<script>
handleResponse({
code: 200,
data: [
{
word: 'jsp'
},
{
word: 'js'
},
{
word: 'json'
},
{
word: 'js 入门'
},
{
word: 'jstl'
}
]
});
</script>
在script里声明函数
const handleResponse = data => {
console.log(data);
};
浏览器输出结果:
2. 动态加载JSONP接口
const script = document.createElement('script');
script.src =
'https://www.imooc.com/api/http/jsonp?callback=handleResponse';
document.body.appendChild(script);
// 声明函数
const handleResponse = data => {
console.log(data);
};
同样可以输出结果: