java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringBoot跨域问题

SpringBoot跨域问题的五种解决方式

作者:跑起来要带风!

前后端分离开发中,跨域问题是很常见的一种问题,下面这篇文章主要给大家介绍了关于SpringBoot跨域问题的五种解决方式,文中通过实例代码介绍的非常详细,需要的朋友可以参考下

一、什么是跨域 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;
   }
}

总结

到此这篇关于SpringBoot跨域问题的五种解决方式的文章就介绍到这了,更多相关SpringBoot跨域问题内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文