什么是跨域?如何解决跨域?
Posted autofelix
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了什么是跨域?如何解决跨域?相关的知识,希望对你有一定的参考价值。
〝 古人学问遗无力,少壮功夫老始成 〞
在大型公司中,都会涉及到前后端分离或者静态资源的单独放一台服务器,这就会经常出现这种情况,比如你的网页时www.autofelix.com,但是你请求的接口却在api.autofelix.com的域名下,由跨域的原理可知,域名不同也会导致跨域问题的出现,当然解决跨域问题的方法有很多,这里提供最常见的几种方式
目录
一、什么是跨域
- 跨域,域是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对javascript实施的安全限制,所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)否则就会造成跨域
二、跨域场景
当前url | 请求url | 是否跨域 | 原因 |
http://www.autofelix.com | http://www.autofelix.com/api.php | 否 | 协议/域名/端口相同 |
http://www.autofelix.com | https://www.autofelix.com/api.php | 是 | 协议不同 |
http://www.autofelix.com | http://www.butofelix.com | 是 | 主域名不同 |
http://www.autofelix.com | http://api.autofelix.com | 是 | 子域名不同 |
http://www.autofelix.com:80 | http://www.autofelix.com:8080 | 是 | 端口不同 |
三、解决跨域的方式
- 常见的跨域解决方式包括下面四种方式:
- nginx的反向代理
- php语言代理
- jsonp请求
- 后端语言的设置
四、nginx的方向代理
- 使用nginx反向代理实现跨域,是最简单的跨域方式。只需要修改nginx的配置即可解决跨域问题,支持所有浏览器,支持session,不需要修改任何代码,并且不会影响服务器性能。
- 通过nginx配置一个代理服务器(域名与domain1相同,端口不同)做跳板机,反向代理访问domain2接口,并且可以顺便修改cookie中domain信息,方便当前域cookie写入,实现跨域登录。
// proxy服务器
server
listen 81;
server_name www.domain1.com;
location /
proxy_pass http://www.domain2.com:8080; #反向代理
proxy_cookie_domain www.domain2.com www.domain1.com; #修改cookie里域名
index index.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;
五、php语言代理
- 这种经常用,比如 www.autofelix.cn 需要调用 api.autofelix.cn/userinfo
- 我们可以这样做,写一个接口 www.autofelix.cn/api.php,由这个接口在后端去调用 api.autofelix.cn/userinfo 并拿到返回值,然后再返回给请求页面
- 这就是一个代理的模式。相当于绕过了浏览器端,因为php不存在跨域,自然就不存在跨域问题
六、jsonp请求
- JSONP 是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,兼容性好(兼容低版本IE),缺点是只支持get请求,不支持post请求。
- 原理时网页通过添加一个
<script>元素
,向服务器请求 JSON 数据,服务器收到请求后,将数据放在一个指定名字的回调函数的参数位置传回来。
//原生实现
<script src="http://autofelix.com/api.php?callback=dosomething"></script>
// 向服务器autofelix.com发出请求,该请求的查询字符串有一个callback参数,用来指定回调函数的名字
// 处理服务器返回回调函数的数据
<script type="text/javascript">
function dosomething(res)
// 处理获得的数据
console.log(res.data)
</script>
//jquery实现
<script>
$.getJSON('http://autofelix.com/api.php&callback=?', function(res)
// 处理获得的数据
console.log(res)
);
</script>
七、后端语言的设置
-
主要通过后端语言主动设置跨域请求,这里以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',
];
/**
* 公共方法调用
*/
static public function setheader()
// 获取当前跨域域名
$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');
以上是关于什么是跨域?如何解决跨域?的主要内容,如果未能解决你的问题,请参考以下文章