乐趣区

关于跨域:一文搞懂│什么是跨域如何解决跨域

🎈 什么是跨域

  • 域: 是指浏览器不能执行其余网站的脚本
  • 跨域: 它是由浏览器的 同源策略 造成的, 是浏览器对 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 {
    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;
    }
}
  • jsonp 申请
  • jsonp 是服务器与客户端跨源通信的罕用办法。最大特点就是简略实用,兼容性好 兼容低版本 IE,毛病是只反对 get 申请,不反对 post 申请
  • 原理时网页通过增加一个 <script> 元素,向服务器申请 json 数据,服务器收到申请后,将数据放在一个指定名字的回调函数的参数地位传回来
//jquery 实现
<script>
$.getJSON('http://autofelix.com/api.php&callback=?', function(res) {
     // 解决取得的数据
     console.log(res)
});
</script>
  • 后端语言代理
  • 能够通过一种没有跨域限度的语言直达一下,通过后端语言去申请资源,而后再返回数据
  • 比方 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');
}
退出移动版