一、初识跨域
1. 跨域是什么
- 同域,不是跨域。
- 不同域,跨域,被浏览器阻止。
- 向一个域发送请求,如果要请求的域和当前域是不同域,就叫跨域。
- 不同域之间的请求,就是跨域请求。
2. 什么是不同域,什么是同域
- https(协议)://www.imooc.com(域名):443(端口号)/course/list(路径)。
协议、域名、端口号,任何一个不一样,就是不同域,与路径无关,路径一不一样无所谓。
不同域:
- https://www.imooc.com:443/course/list
- http://www.imooc.com:80/course/list
- http://m.imooc.com:80/course/list
- http://imooc.com:80/course/list
- 同域:
- http://imooc.com:80
- http://imooc.com:80/course/list
3. 跨域请求为什么会被阻止
- 阻止跨域请求,其实是浏览器本身的一种安全策略--同源策略。
- 其他客户端或者服务器都不存在跨域被阻止的问题。
4. 跨域解决方案
- ① CORS 跨域资源共享
- ② JSONP
优先使用 CORS 跨域资源共享,如果浏览器不支持 CORS 的话,再使用 JSONP。
二、CORS 跨域资源共享
1. CORS 是什么
- CORS 跨域资源共享本质上是后端在解决。
- 后端会在响应头中加入 Access-Control-Allow-Origin:* 属性,表明允许所有的域名来跨域请求它,* 是通配符,没有任何限制。
Access-Control-Allow-Origin: http://127.0.0.1:5500 则表示只允许指定域名的跨域请求。
2. 使用 CORS 跨域的过程
- ① 浏览器发送请求。
- ② 后端在响应头中添加 Access-Control-Allow-Origin 头信息。
- ③ 浏览器接收到响应。
- ④ 如果是同域下的请求,浏览器不会额外做什么,这次前后端通信就圆满完成了。
- ⑤ 如果是跨域请求,浏览器会从响应头中查找是否允许跨域访问。
- ⑥ 如果允许跨域,通信圆满完成。
- ⑦ 如果没找到或不包含想要跨域的域名,就丢弃响应结果。
3. CORS 的兼容性
- IE10 及以上版本的浏览器可以正常使用 CORS。
三、JSONP
1. JSONP 的原理
- script 标签跨域不会被浏览器阻止,例如:script 标签可以加载外部的(互联网上的)js文件。
- JSONP 主要就是利用 script 标签,加载跨域文件。
2. 使用 JSONP 实现跨域
- 服务器端准备好 JSONP 接口。
- JSONP 接口中的内容
// 相当于 handleResponse 函数的调用。 handleResponse({ "code": 200, "data": [ { "word": "jsp" }, { "word": "js" }, { "word": "json" }, { "word": "js 入门" }, { "word": "jstl" } ] });
- 手动加载 JSONP 接口
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>使用 JSONP 实现跨域</title> </head> <body> <script> // 声明函数 const handleResponse = data => { console.log(data); } </script> <!-- 手动加载 JSONP 接口 --> <script src="https://www.imooc.com/api/http/jsonp?callback=handleResponse"></script> </body> </html>
- 动态加载 JSONP 接口
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>使用 JSONP 实现跨域</title> </head> <body> <script> // 声明函数 const handleResponse = data => { console.log(data); } // 动态加载 JSONP 接口 const script = document.createElement('script'); script.src = 'https://www.imooc.com/api/http/jsonp?callback=handleResponse'; document.body.appendChild(script); </script> </body> </html>
- 结果