龙哥网

龙哥网

SpringBoot跨域问题的五种解决方式_java(springboot跨域问题怎么解决)
2022-03-01

目录
  • 一、什么是跨域 CORS
  • 二、为什么会有跨域问题
  • 三、有哪些跨域类型
  • 四、解决跨域问题的五种方式
    • 1. 添加跨域配置类
    • 2. 重写WebMvcConfigurer
    • 3. 注解 @CrossOrigin
    • 4. 自定义过滤器
    • 5. 手动设置响应头
  • 前后分离的跨域问题其他解决方案
    • Nginx服务器反向代理
    • 或者直接在Nginx中进行配置
  • 总结

    一、什么是跨域 CORS

    当一台服务器资源从另一台服务器(不同 的域名或者端口)请求一个资源或者接口,就会发起一个跨域 HTTP 请求。

    举个简单的例子,从http://aaa.com/index.html,发送一个 Ajax 请求,请求地址是 http://bbb.com/下面的一个接口,这就是发起了一个跨域请求。在不做任何处理的情况下,这个跨域请求是无法被成功请求的

    现在很多项目开发都是前后端分离的,前端和后端都是独立运行的,后端提供json数据格式。那么两边是不同的ip、端口,跨站点进行资源分享,就是跨域。所以前后端分离就肯定有跨域问题。

    二、为什么会有跨域问题

    浏览器出于安全考虑,会限制跨域访问,就是不允许跨域请求资源,要求协议,IP和端口必须都相同,其中有一个不同就会产生跨域问题,这就是同源策略。

    三、有哪些跨域类型

    简单来说,就是协议、域名(主域或子域)、端口号有一个不同就是跨域。

    四、解决跨域问题的五种方式

    1. 添加跨域配置类

    * 号根据需要修改。

    @Configuration
    public class GlobalCorsConfig {
    
        @Bean
        public CorsFilter corsFilter() {
            //1. 添加 CORS配置信息
            CorsConfiguration config = new CorsConfiguration();
            //放行哪些原始域
            config.addAllowedOrigin("*");
            //是否发送 Cookie
            config.setAllowCredentials(true);
            //放行哪些请求方式
            config.addAllowedMethod("*");
            //放行哪些原始请求头部信息
            config.addAllowedHeader("*");
            //暴露哪些头部信息
            config.addExposedHeader("*");
            //2. 添加映射路径
            UrlBasedCorsConfigurationSource corsConfigurationSource = new UrlBasedCorsConfigurationSource();
            corsConfigurationSource.registerCorsConfiguration("/**",config);
            //3. 返回新的CorsFilter
            return new CorsFilter(corsConfigurationSource);
        }
    }
    
    

    2. 重写WebMvcConfigurer

    @Configuration
    public class CorsConfig implements WebMvcConfigurer {
    
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    //是否发送Cookie
                    .allowCredentials(true)
                    //放行哪些原始域
                    .allowedOrigins("*")
                    .allowedMethods(new String[]{"GET", "POST", "PUT", "DELETE"})
                    .allowedHeaders("*")
                    .exposedHeaders("*");
        }
    }
    
    

    3. 注解 @CrossOrigin

    在控制器(类上)上使用注解 @CrossOrigin,表示该类的所有方法允许跨域

    @RestController
    @CrossOrigin(origins = "*")
    public class HelloController {
    
        @RequestMapping("/hello")
        public String hello() {
            return "hello world";
        }
    }
    
    

    在方法上使用注解 @CrossOrigin,表示该方法允许跨域

    @RequestMapping("/hello")
    @CrossOrigin(origins = "*")
     //@CrossOrigin(value = "http://localhost:8081") //指定具体ip允许跨域
    public String hello() {
          return "hello world";
    }
    
    

    4. 自定义过滤器

    import java.io.IOException;
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.springframework.stereotype.Component;
    
    @Component
    public class MyCorsFilter implements Filter {
    
        public void doFilter(ServletRequest req, ServletResponse res,
                             FilterChain chain) throws IOException, ServletException {
    
            HttpServletResponse response = (HttpServletResponse) res;
            HttpServletRequest httpServletRequest = (HttpServletRequest) req;
            response.setHeader("Access-Control-Allow-Origin", httpServletRequest.getHeader("origin"));
            response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, HEAD");
            response.setHeader("Access-Control-Max-Age", "3600");
            response.setHeader("Access-Control-Allow-Headers", "access-control-allow-origin, authority, content-type, version-info, X-Requested-With");
            response.setHeader("Access-Control-Allow-Credentials", "true");
            chain.doFilter(req, res);
    
        }
    
        public void init(FilterConfig filterConfig) {}
        public void destroy() {}
    }
    

    5. 手动设置响应头

    在接口的代码中添加下面这端代码。

     response.addHeader("Access-Control-Allow-Origin", "*");
     response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
     response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
     response.addHeader("Access-Control-Max-Age", "1800");//30 min

    前后分离的跨域问题其他解决方案

    Nginx服务器反向代理

    通过反向代理服务器监听同端口,同域名的访问,不同路径映射到不同的地址,比如,在nginx服务器中,监听同一个域名和端口,不同路径转发到客户端和服务器,把不同端口和域名的限制通过反向代理,来解决跨域的问题。

    server {
            listen       80;
            server_name  abc.com;
            #charset koi8-r;
            #access_log  logs/host.access.log  main;
    
            location /client { #访问客户端路径
                proxy_pass http://localhost:81;
                proxy_redirect default;
            }
            location /apis { #访问服务器路径
                rewrite  ^/apis/(.*)$ /$1 break;
                proxy_pass   http://localhost:82;
           }
    }
    

    或者直接在Nginx中进行配置

    location / {
       add_header Access-Control-Allow-Origin *;
       add_header Access-Control-Allow-Headers X-Requested-With;
       add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
    
       if ($request_method = 'OPTIONS') {
         return 204;
       }
    }
    
    

    总结

    免责声明
    本站部分资源来源于互联网 如有侵权 请联系站长删除
    龙哥网是优质的互联网科技创业资源_行业项目分享_网络知识引流变现方法的平台为广大网友提供学习互联网相关知识_内容变现的方法。