zoukankan      html  css  js  c++  java
  • SpringBoot系列(八)分分钟学会Springboot多种解决跨域方式

    SpringBoot系列(八) 分分钟学会SpringBoot多种跨域解决方式

    往期推荐
    SpringBoot系列(一)idea新建Springboot项目

    SpringBoot系列(二)入门知识

    springBoot系列(三)配置文件详解

    SpringBoot系列(四)web静态资源配置详解

    SpringBoot系列(五)Mybatis整合完整详细版

    SpringBoot系列(六)集成thymeleaf详解版

    Springboot系列(七) 集成接口文档swagger,使用,测试

    ** 目录 **

    1. 跨域怎么理解

    跨域是什么?

     跨域是指不同域名之间的相互访问,这是由浏览器的同源策略决定的,是浏览器对JavaScript施加的安全措施,防止恶意文件破坏。

    同源策略:同源策略是一种约定,它是浏览器最核心的也是最基本的安全策略,如果缺少了同源策略,则浏览器的正常功能可能会受到影响。
    所谓同源就是说协议域名端口号完全一致,有一个不一致就会造成跨域问题。

    跨域原理:

    • 跨域请求能正常发出去,服务端能接受到请求并正常返回结果,只是结果被拦截了。
    • 跨域只存在于浏览器,不存在于其他平台,比如安卓/java/ios等平台。
    • 之所以会发生跨域是因为受到了同源策略的限制,同源策略要求源相同才能进行正常通信,即协议,域名,端口号都完全一致。

    URL :统一资源定位符,它是www的统一资源定位标志,也就是我们说的网络地址。它的一般格式为:协议类型://服务器地址:端口号/路径。
    这也就是我们说的跨域中的域。

    2. SprinBoot中跨域的三种解决方法

    跨域技术CORS

     CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。

     SpringBoot 就对Cross 做了很好的支持。目前有三种跨域方式。

    1. CrossOrigin注解

    //@CrossOrigin  表示所有的URL均可访问此资源
    @CrossOrigin(origins = "http://127.0.0.1:8093")//表示只允许这一个url可以跨域访问这个controller
    @RestController
    @RequestMapping("/testCorss")
    public class CorssOriginController {
    
        //可以对方法运用该注解
        //@CrossOrigin(origins = "http://127.0.0.1:8093")
        @GetMapping("/getString")
        public String getString(){
            return "跨域成功!";
        }
    
    }
    

     代码说明:@CrossOrigin这个注解用起来很方便,这个可以用在方法上,也可以用在类上。如果你不设置他的value属性,或者是origins属性,就默认是可以允许所有的URL/域访问。

    • value属性可以设置多个URL。
    • origins属性也可以设置多个URL。
    • maxAge属性指定了准备响应前的缓存持续的最大时间。就是探测请求的有效期。
    • allowCredentials属性表示用户是否可以发送、处理 cookie。默认为false
    • allowedHeaders 属性表示允许的请求头部有哪些。
    • methods 属性表示允许请求的方法,默认get,post,head。

    2. 实现WebMvcConfigurer

    /**
     * @author 全栈学习笔记
     * @date 2020/4/21 12:04
     * @description
     */
    public class MyWebMvcConfig implements WebMvcConfigurer {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/testCross/**")
                    .allowedHeaders("*")
                    .allowedMethods("*")
                    .allowCredentials(true)
                    .allowedOrigins("http://localhost:8093")
                    .maxAge(2000);
        }
    }
    

     这个没什么好说的,就重写addCorsMappings方法就行,配置好参数,参数和上面的注解的参数类似。这个配置属于全局配置,配置好了全部的接口都遵循此规则。上面的注解方式只对类或者方法生效。addMaping是设置对那种格式的URL生效,也就是跟在URL后面的路径。

    3. 过滤器配置

    
    import org.springframework.boot.web.servlet.FilterRegistrationBean;
    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 全栈学习笔记
     * @date 2020/4/21 12:49
     * @description
     */
    @Configuration
    public class Filter {
        @Bean
        public FilterRegistrationBean corsFilter() {
            UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            CorsConfiguration config = new CorsConfiguration();
            config.setAllowCredentials(true);
            config.addAllowedOrigin("http://localhost:8093");//*表示允许所有
            config.addAllowedHeader("*");
            config.addAllowedMethod("*");
            source.registerCorsConfiguration("/**", config); // CORS 配置对所有接口都有效
            FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
            bean.setOrder(0);
            return bean;
        }
    
    }
    

     利用过滤器配置实现跨域,还有另外一种方法

    package com.example.democrossorigin.config;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.stereotype.Component;
    
    import javax.servlet.*;
    import javax.servlet.FilterConfig;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    @Configuration
    public class CorssFilter implements Filter {
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            HttpServletResponse res = (HttpServletResponse) response;
            res.addHeader("Access-Control-Allow-Credentials", "true");
            res.addHeader("Access-Control-Allow-Origin", "http://localhost:8093");
            res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
            res.addHeader("Access-Control-Allow-Headers", "Content-Type,X-CAF-Authorization-Token,sessionToken,X-TOKEN");
            chain.doFilter(request, response);
        }
        @Override
        public void destroy() {
        }
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
        }
    }
    
    

    3. 跨域测试

     我们在新建一个SpringBoot web项目,然后在resources 文件夹里面的static 新建一个index.html
    代码如下

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
    </head>
    <body>
    <div id="test"></div>
    <input type="button" value="测试数据" onclick="getString()"/>
    </body>
    <script>
    
        function getString() {
            $.ajax({
                url:'http://localhost:8092/testCorss/getString',
                type:'get',
                data:{},
                success:function (msg) {
                    $("#test").html(msg);
                }
            })
        }
    </script>
    </html>
    

     我们模拟一个ajax请求,来请求我们的8092端口,运行新的项目结果

     点击测试,发起请求

     成功从一个项目里面拿到了另外一个项目的数据,就说明我们的跨域是成功了的。

    4.总结:##

     本文讲述了跨域的产生原因,原理,以及同源策略的概念,然后介绍了在SpringBoot解决跨域的三种方式,分别是利用CrossOrgin注解,全局配置Mvc,然后就是利用过滤器配置,过滤器有两种方式,有一种是利用servlet的过滤器实现。如果你觉得本文有用的话!点个赞也不错哦!你的赞是对我最大的鼓励和支持。

  • 相关阅读:
    同源策略和跨域知识点学习
    一次脚本注入广告漏洞分析
    一个利用微信分享的项目开发过程以及后续思考
    react-native —— 在Windows下搭建React Native Android开发环境
    ionic —— 开发环境搭建并编译运行第一个APP
    错误: 找不到或无法加载主类
    jekyll and github.io搭建博客遇到的问题
    java 10 生成头文件
    JNI的使用
    vivado error:incorrect freePtr. Call out of sequence?
  • 原文地址:https://www.cnblogs.com/swzx-1213/p/12745086.html
Copyright © 2011-2022 走看看