简单而言,跨域请求就是当一台服务器资源从另一台服务器(不同 的域名或者端口)请求一个资源或者接口,就会发起一个跨域 HTTP 请求。举个简单的例子,从 http://www.baidu.com ,发送一个 Ajax 请求,请求地址是 http://www.taobao.com 下面的一个接口,这就是发起了一个跨域请求,在不做任何处理的情况下,显然当前跨域请求是无法被成功请求,因为浏览器基于同源策略会对跨域请求做一定的限制。
例如: http://127.0.0.1:8080
当协议、IP、端口三部分中有任意一个不同时,即为跨域。
通过设置Access-Control-Allow-Origin来实现跨域访问。
使用Filter过滤器来过滤服务请求,向请求端设置Response Header(响应头部)的Access-Control-Allow-Origin属性声明允许跨域访问。
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; @Configuration public class CorsConfig { @Bean public CorsFilter corsFilter() { CorsConfiguration config = new CorsConfiguration(); // 允许跨域的源地址 // 在Springboot2.4对应Spring5.3后在设置allowCredentials(true)的基础上不能直接使用通配符设置allowedOrigins,而是需要指定特定的URL。如果需要设置通配符,需要通过allowedOriginPatterns指定 config.addAllowedOrigin("*"); //config.allowedOriginPatterns("*"); // 允许用户凭证跨域(cookie、HTTP认证及客户端SSL证明等) //config.setAllowCredentials(true); // 允许跨域的头部 config.addAllowedHeader("*"); // 允许跨域的方法 config.addAllowedMethod("*"); // 当前跨域请求最大有效时长,单位:秒 config.setMaxAge(1800L); // 跨域路径配置 UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", config); return new CorsFilter(source); } }
或者
import org.springframework.web.filter.OncePerRequestFilter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebFilter public class CorsFilter implements Filter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // 允许跨域的源地址 response.setHeader("Access-Control-Allow-Origin", "*"); // 允许跨域的头部 response.setHeader("Access-Control-Allow-Methods", "*"); // 允许跨域的方法 response.setHeader("Access-Control-Allow-Headers", "*"); // 允许用户凭证跨域(cookie、HTTP认证及客户端SSL证明等) response.setHeader("Access-Control-Allow-Credentials", "true"); // 当前跨域请求最大有效时长,单位:秒 response.setHeader("Access-Control-Max-Age", "1800"); filterChain.doFilter(request, response); } }
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; @Configuration public class CorsConfig { @Bean public FilterRegistrationBean<CorsFilter> corsFilterRegistrationBean(){ CorsConfiguration config = new CorsConfiguration(); // 允许跨域的源地址 // 在Springboot2.4对应Spring5.3后在设置allowCredentials(true)的基础上不能直接使用通配符设置allowedOrigins,而是需要指定特定的URL。如果需要设置通配符,需要通过allowedOriginPatterns指定 config.addAllowedOrigin("*"); //config.allowedOriginPatterns("*"); // 允许用户凭证跨域(cookie、HTTP认证及客户端SSL证明等) //config.setAllowCredentials(true); // 允许跨域的头部 config.addAllowedHeader("*"); // 允许跨域的方法 config.addAllowedMethod("*"); // 当前跨域请求最大有效时长,单位:秒 config.setMaxAge(1800L); // 跨域路径配置 UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", config); FilterRegistrationBean<CorsFilter> registration = new FilterRegistrationBean<>(); registration.setFilter(new CorsFilter(source)); // 设置执行顺序,数字越小越先执行 bean.setOrder(0); return bean; } }
import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/") // @CrossOrigin public class HelloController { @CrossOrigin @GetMapping("/hello") public String hello() { return "success"; } @GetMapping("/test") public String test() { return "failure"; } }
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { CorsRegistration cors = registry.addMapping("/**"); // 允许跨域的源地址 // 在Springboot2.4对应Spring5.3后在设置allowCredentials(true)的基础上不能直接使用通配符设置allowedOrigins,而是需要指定特定的URL。如果需要设置通配符,需要通过allowedOriginPatterns指定 cors.allowedOrigins("*"); //cors.allowedOriginPatterns("*"); // 允许用户凭证跨域(cookie、HTTP认证及客户端SSL证明等) cors.allowCredentials(true); // 设置 header 能携带的信息 cors.allowedHeaders("*"); // 支持跨域的请求方法 cors.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS"); // 设置跨域过期时间,单位为秒 cors.maxAge(3600); } }
location / { #支持跨域访问 add_header Access-Control-Allow-Origin $http_origin; add_header Access-Control-Allow-Credentials true; add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS; add_header Access-Control-Allow-Headers X-Requested-With,Authorization,Content-Type,Accept,Origin; add_header Access-Control-Expose-Headers Content-Length,Content-Range; if ($request_method = 'OPTIONS') { return 204; } proxy_pass http://127.0.0.1:8080/; proxy_redirect default; }
打开浏览器并打开任意第三方网页,F12打开浏览器开发者工具,根据实际需要测试的请求地址,输入如下代码:
var x = new XMLHttpRequest(); x.open('GET','http://127.0.0.1:8080/test'); x.send(null); x.onload = function(e) { var x = e.target; console.log(x.responseText); }