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


    🎈 什么是跨域#

    • 域: 是指浏览器不能执行其他网站的脚本
    • 跨域: 它是由浏览器的 同源策略 造成的,是浏览器对 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');
    }
    
  • 相关阅读:
    特殊SQL的执行(模糊查询、批量删除、动态设置表名、添加功能获取自增的主键)
    C++内存管理
    因为 QUERY_ALL_PACKAGES 权限,我们上不了 Google Play 了
    【MATLAB源码-第48期】基于matlab的16QAM信号盲解调仿真。
    RESTful 基础知识
    Anaconda虚拟环境下打开jupyter notebook
    怎样在CSDN赚点零花钱
    【Python&GIS】基于Python批量合并矢量数据
    Deformable Convolution 可变形卷积
    【golang】go app 优雅关机 Graceful Shutdown How?
  • 原文地址:https://www.cnblogs.com/autofelix/p/16481198.html