什么是跨域?如何解决跨域?

Posted autofelix

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了什么是跨域?如何解决跨域?相关的知识,希望对你有一定的参考价值。

〝 古人学问遗无力,少壮功夫老始成 〞

在大型公司中,都会涉及到前后端分离或者静态资源的单独放一台服务器,这就会经常出现这种情况,比如你的网页时www.autofelix.com,但是你请求的接口却在api.autofelix.com的域名下,由跨域的原理可知,域名不同也会导致跨域问题的出现,当然解决跨域问题的方法有很多,这里提供最常见的几种方式

目录

 一、什么是跨域

二、跨域场景

三、解决跨域的方式

四、nginx的方向代理

五、php语言代理

六、jsonp请求

七、后端语言的设置


 一、什么是跨域

  • 跨域,域是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对javascript实施的安全限制,所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)否则就会造成跨域

二、跨域场景

当前url请求url是否跨域原因
http://www.autofelix.comhttp://www.autofelix.com/api.php协议/域名/端口相同
http://www.autofelix.comhttps://www.autofelix.com/api.php协议不同
http://www.autofelix.comhttp://www.butofelix.com主域名不同
http://www.autofelix.comhttp://api.autofelix.com子域名不同
http://www.autofelix.com:80http://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');
   

以上是关于什么是跨域?如何解决跨域?的主要内容,如果未能解决你的问题,请参考以下文章

一文搞懂│什么是跨域?如何解决跨域?

一文搞懂│什么是跨域?如何解决跨域?

SpringBoot - 什么是跨域?如何解决跨域?

到底什么是跨域?如何解决跨域问题

什么是跨域,以及解决方案

什么是跨域?如何解决跨域?