一文搞懂│什么是跨域(如何解决跨域?)
什么是跨域
- 域: 是指浏览器不能执行其他网站的脚本
- 跨域: 它是由浏览器的 同源策略 造成的,是浏览器对
JavaScript
实施的安全限制,所谓同源(即指在同一个域)就是两个页面具有相同的协议protocol
,主机host
和端口号port
则就会造成 跨域
文章图片
跨域场景
- 场景的跨域场景有哪些,请参考下表
当前url | 请求url | 是否跨域 | 原因 |
---|---|---|---|
http://www.autofelix.cn |
http://www.autofelix.cn/api.php |
否 | 协议/域名/端口都相同 |
http://www.autofelix.cn |
https://www.autofelix.cn/api.php |
是 | 协议不同 |
http://www.autofelix.cn |
http://www.rabbit.cn |
是 | 主域名不同 |
http://www.autofelix.cn |
http://api.autofelix.cn |
是 | 子域名不同 |
http://www.autofelix.cn:80 |
http://www.autofelix.cn:8080 |
是 | 端口不同 |
- nginx的反向代理
- 使用
nginx
反向代理实现跨域,是最简单的跨域方式 - 只需要修改
nginx
的配置即可解决跨域问题,支持所有浏览器,支持session
,不需要修改任何代码,并且不会影响服务器性能
// nginx配置
server {
listen81;
server_namewww.domain1.com;
location / {
proxy_passhttp://www.domain2.com:8080;
#反向代理
proxy_cookie_domain www.domain2.com www.domain1.com;
#修改cookie里域名
indexindex.html index.htm;
# 当用webpack-dev-server等中间件代理接口访问nignx时,此时无浏览器参与,故没有同源限制,下面的跨域配置可不启用
add_header Access-Control-Allow-Origin http://www.domain1.com;
#当前端只跨域不带cookie时,可为*
add_header Access-Control-Allow-Credentials true;
}
}
- jsonp请求
jsonp
是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,兼容性好兼容低版本IE
,缺点是只支持get
请求,不支持post
请求- 原理时网页通过添加一个
- 后端语言代理
- 可以通过一种没有跨域限制的语言中转一下,通过后端语言去请求资源,然后再返回数据
- 比如
http://www.autofelix.cn
需要调用http://api.autofelix.cn/userinfo
去获取用户数据,因为子域名不同,会有跨域限制 - 可以先请求
http://www.autofelix.cn
下的php
文件,比如http://www.autofelix.cn/api.php
,然后再通过该php
文件返回数据
// api.php 文件中的代码 public function getCurl($url, $timeout = 5) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); $result = curl_exec($ch); curl_close($ch); return $result; }$result = getCurl('http://api.autofelix.cn/userinfo'); return $result;
- 后端语言的设置
- 主要通过后端语言主动设置跨域请求,这里以
php
作为案例
// 允许所有域名访问 header('Access-Control-Allow-Origin: *'); // 允许单个域名访问 header('Access-Control-Allow-Origin: https://autofelix.com'); // 允许多个自定义域名访问 static public $originarr = [ 'https://autofelix.com', 'https://baidu.com', 'https://csdn.net', ]; // 获取当前跨域域名 $origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : ''; if (in_array($origin, self::$originarr)) { // 允许 $originarr 数组内的 域名跨域访问 header('Access-Control-Allow-Origin:' . $origin); // 响应类型 header('Access-Control-Allow-Methods:POST,GET'); // 带 cookie 的跨域访问 header('Access-Control-Allow-Credentials: true'); // 响应头设置 header('Access-Control-Allow-Headers:x-requested-with,Content-Type,X-CSRF-Token'); }
推荐阅读
- 搞懂react类组件中的this指向
- 投稿|一文搞懂板块之王“新能源汽车”的现状和未来
- 网友来稿(何为正则(一正则天下,一文带你看尽精华。))
- 【图】3分钟搞懂顶级域名|【图】3分钟搞懂顶级域名|二级域名|子域名|父域名的区别
- {调取该文章的TAG关键词}|三大航空公司2500亿“团购”292架飞机,一文读懂国内史上最大订单|钛度图闻
- 一文搞懂│工厂模式、单例模式、策略模式、适配器模式、观察者模式的原理和使用
- 开篇第一文,聊点CRM之外的话题
- 一口气搞懂「文件系统」,就靠这 25 张图了
- 一文带你领略并发编程的内功心法
- 一文教会你微信小程序如何实现登录