zoukankan      html  css  js  c++  java
  • 网站跨域的五种解决方式

    1、什么是跨越?

    • 一个网页向另一个不同域名/不同协议/不同端口的网页请求资源,这就是跨域。
    • 跨域原因产生:在当前域名请求网站中,默认不允许通过ajax请求发送其他域名。

    2、为什么会产生跨域请求?

    • 因为浏览器使用了同源策略

    3、什么是同源策略?

    • 同源策略是Netscape提出的一个著名的安全策略,现在所有支持JavaScript的浏览器都会使用这个策略。同源策略是浏览器最核心也最基本的安全功能,如果缺少同源策略,浏览器的正常功能可能受到影响。可以说web是构建在同源策略的基础之上的,浏览器只是针对同源策略的一种实现。

    4、为什么浏览器要使用同源策略?

    • 是为了保证用户的信息安全,防止恶意网站窃取数据,如果网页之间不满足同源要求,将不能:

      • 1、共享Cookie、LocalStorage、IndexDB
      • 2、获取DOM
      • 3、AJAX请求不能发送

    同源策略的非绝对性:

    <script></script>
    <img/>
    <iframe/>
    <link/>
    <video/>
    <audio/>
    

    等带有src属性的标签可以从不同的域加载和执行资源。其他插件的同源策略:flash、java applet、silverlight、googlegears等浏览器加载的第三方插件也有各自的同源策略,只是这些同源策略不属于浏览器原生的同源策略,如果有漏洞则可能被黑客利用,从而留下XSS攻击的后患

    所谓的同源指:域名、网络协议、端口号相同,三条有一条不同就会产生跨域。 例如:你用浏览器打开http://baidu.com,浏览器执行JavaScript脚本时发现脚本向http://cloud.baidu.com域名发请求,这时浏览器就会报错,这就是跨域报错。

    解决方案有五:

    1、前端使用jsonp (不推荐使用)

    • 当我们正常地请求一个JSON数据的时候,服务端返回的是一串 JSON类型的数据,而我们使用 JSONP模式来请求数据的时候服务端返回的是一段可执行的 JavaScript代码。因为jsonp 跨域的原理就是用的动态加载 script的src ,所以我们只能把参数通过 url的方式传递,所以jsonp的 type类型只能是get示例:
    $.ajax({
        url: 'http://192.168.1.114/yii/demos/test.php', //不同的域
        type: 'GET', // jsonp模式只有GET 是合法的
        data: {
            'action': 'aaron'
        },
        dataType: 'jsonp', // 数据类型
        jsonp: 'backfunc', // 指定回调函数名,与服务器端接收的一致,并回传回来
    })
    
    • 使用JSONP 模式来请求数据的整个流程:客户端发送一个请求,规定一个可执行的函数名(这里就是 jQuery做了封装的处理,自动帮你生成回调函数并把数据取出来供success属性方法来调用,而不是传递的一个回调句柄),服务器端接受了这个 backfunc函数名,然后把数据通过实参的形式发送出去
    • (在jquery 源码中, jsonp的实现方式是动态添加<script>标签来调用服务器提供的 js脚本。jquery 会在window对象中加载一个全局的函数,当 <script>代码插入时函数执行,执行完毕后就 <script>会被移除。同时jquery还对非跨域的请求进行了优化,如果这个请求是在同一个域名下那么他就会像正常的 Ajax请求一样工作。)

    2、后台Http请求转发

    • 使用HttpClinet转发进行转发(简单的例子 不推荐使用这种方式)
    try {
        HttpClient client = HttpClients.createDefault();            //client对象
        HttpGet get = new HttpGet("http://localhost:8080/test");    //创建get请求
        CloseableHttpResponse response = httpClient.execute(get);   //执行get请求
        String mes = EntityUtils.toString(response.getEntity());    //将返回体的信息转换为字符串
        System.out.println(mes);
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    

    3、后台配置同源Cors (推荐)

    • 在SpringBoot2.0 上的跨域 用以下代码配置 即可完美解决你的前后端跨域请求问题

    在SpringBoot2.0 上的跨域 用以下代码配置 即可完美解决你的前后端跨域请求问题

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.cors.CorsConfiguration;
    import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
    import org.springframework.web.filter.CorsFilter;
    
    /**
     * 实现基本的跨域请求
     * @author linhongcun
     *
     */
    @Configuration
    public class CorsConfig {
    
        @Bean
        public CorsFilter corsFilter() {
            final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
            final CorsConfiguration corsConfiguration = new CorsConfiguration();
            /*是否允许请求带有验证信息*/
            corsConfiguration.setAllowCredentials(true);
            /*允许访问的客户端域名*/
            corsConfiguration.addAllowedOrigin("*");
            /*允许服务端访问的客户端请求头*/
            corsConfiguration.addAllowedHeader("*");
            /*允许访问的方法名,GET POST等*/
            corsConfiguration.addAllowedMethod("*");
            urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
            return new CorsFilter(urlBasedCorsConfigurationSource);
        }
    
    
    
    }
    

    4、使用SpringCloud网关

    • 服务网关(zuul)又称路由中心,用来统一访问所有api接口,维护服务。

    • Spring Cloud Zuul通过与Spring Cloud Eureka的整合,实现了对服务实例的自动化维护,所以在使用服务路由配置的时候,我们不需要向传统路由配置方式那样去指定具体的服务实例地址,只需要通过Ant模式配置文件参数即可

    5、使用nginx做转发

    • 现在有两个网站想互相访问接口  在http://a.a.com:81/A中想访问 http://b.b.com:81/B 那么进行如下配置即可
    • 然后通过访问 www.my.com/A 里面即可访问 www.my.com/B
    server {
            listen       80;
            server_name  www.my.com;
            location /A {
    		    proxy_pass  http://a.a.com:81/A;
    			index  index.html index.htm;
            }
    		location /B {
    		    proxy_pass  http://b.b.com:81/B;
    			index  index.html index.htm;
            }
        }
    
    • 如果是两个端口想互相访问接口  在http://b.b.com:80/Api中想访问 http://b.b.com:81/Api 那么进行如下配置即可
    • 使用nginx转发机制就可以完成跨域问题
    server {
            listen       80;
            server_name  b.b.com;
            location /Api {
    		    proxy_pass  http://b.b.com:81/Api;
    			index  index.html index.htm;
            }
        }
    
  • 相关阅读:
    0593. Valid Square (M)
    0832. Flipping an Image (E)
    1026. Maximum Difference Between Node and Ancestor (M)
    0563. Binary Tree Tilt (E)
    0445. Add Two Numbers II (M)
    1283. Find the Smallest Divisor Given a Threshold (M)
    C Primer Plus note9
    C Primer Plus note8
    C Primer Plus note7
    C Primer Plus note6
  • 原文地址:https://www.cnblogs.com/rolandlee/p/10767600.html
Copyright © 2011-2022 走看看