SpringBoot跨域问题
跑起来要带风! 人气:0一、什么是跨域 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; } }
总结
加载全部内容