CORS跨域请求以及spring boot集成

2017-10-25 08:22:48来源:CSDN作者:crazyzhb2012人点击

分享

同源策略 (same origin policy) 是浏览器安全的基石。在同源策略的限制下,非同源的网站之间不能发送 ajax 请求的。为了解决这个问题,W3C提出了CROS
CROS Cross-Origin Resource Sharing 跨域资源共享

简单请求

跨源时能够通过 script 或者 image 标签触发 GET 请求或通过表单发送一条 POST 请求,但这两种请求 HTTP 头信息中都不能包含任何自定义字段。
请求方法是 HEAD、GET 或 POST 且 HTTP 头信息不超过以下几个字段:Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type(只限于 application/x-www-form-urlencoded、multipart/form-data、text/plain)
ajax 进行跨域请求
如果需要ajax来请求的话,在头信息中添加一个 Origin 字段, 根据字段来判断是否需要在http响应头上添加Access-Control-Allow-Origin 字段,是否返回正确的结果。
因为浏览器先于用户得到返回结果,根据有无 Access-Control-Allow-Origin 字段来决定是否拦截该返回结果。

其他的参数
Access-Control-Allow-Credentials:可选,用户是否可以发送、处理 cookie。
Access-Control-Expose-Headers:可选,可以让用户拿到的字段。有几个字段无论设置与否都可以拿到的,包括:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。

非简单请求(除简单请求之外的)

需要增加一次OPTIONS请求,称为预检请求,预检请求将真实请求的信息,包括请求方法、自定义头字段、源信息添加到 HTTP 头信息字段中,询问服务器是否允许这样的操作。
比如 delete 请求

OPTIONS /test HTTP/1.1Origin: http://www.examples.comAccess-Control-Request-Method: DELETEAccess-Control-Request-Headers: X-Custom-HeaderHost: www.examples.com

与 CORS 相关的字段有:

Access-Control-Request-Method: 真实请求使用的 HTTP 方法。
Access-Control-Request-Headers: 真实请求中包含的自定义头字段。
服务器收到请求时,需要分别对 Origin、Access-Control-Request-Method、Access-Control-Request-Headers 进行验证,验证通过后,会在返回 Http 头信息中添加

Access-Control-Allow-Origin: http://www.examples.comAccess-Control-Allow-Methods: GET, POST, PUT, DELETEAccess-Control-Allow-Headers: X-Custom-HeaderAccess-Control-Allow-Credentials: trueAccess-Control-Max-Age: 1728000

他们的含义分别是:

Access-Control-Allow-Methods: 真实请求允许的方法
Access-Control-Allow-Headers: 服务器允许使用的字段
Access-Control-Allow-Credentials: 是否允许用户发送、处理 cookie
Access-Control-Max-Age: 预检请求的有效期,单位为秒。有效期内,不会重复发送预检请求
当预检请求通过后,浏览器会发送真实请求到服务器。这就实现了跨源请求。

spring boot集成CORS

单个类或者url配置

CrossOrigin(origins = {"http://localhost:9000", "null"})

全局配置

方式一 使用CorsConfiguration

@Beanpublic FilterRegistrationBean corsFilter() {    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();    CorsConfiguration config = new CorsConfiguration();    config.setAllowCredentials(true);   config.addAllowedOrigin("http://localhost:9000");    config.addAllowedOrigin("null");    config.addAllowedHeader("*");    config.addAllowedMethod("*");    source.registerCorsConfiguration("/**", config); // CORS 配置对所有接口都有效    FilterRegistrationBean bean = newFilterRegistrationBean(new CorsFilter(source));    bean.setOrder(0);    return bean;}

ps 这里的CorsFilter 是org.springframework.web.filter, 他最终实现的是javax.servlet.Filter
方式二 自定义Filter, 这种方式更加灵活
新增一个类corsFilter,实现Filter接口,在doFilter方法里面,对response添加header,加origin.

@Component("corsFilter") public class CorsFilter implements Filter {    @Override    public void init(FilterConfig filterConfig) throws ServletException {    }    @Override    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {        if (response instanceof HttpServletResponse) {            HttpServletResponse httpResponse = (HttpServletResponse) response;            httpResponse.addHeader("Access-Control-Allow-Origin", "*");            httpResponse.addHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");            httpResponse.addHeader("Access-Control-Allow-Headers", "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With");        }        chain.doFilter(request, response);    }    @Override    public void destroy() {    }}
@Bean    public FilterRegistrationBean additionalFilterRegistration() {        FilterRegistrationBean registration = new FilterRegistrationBean();        registration.setFilter(corsFilter);        registration.setEnabled(true);        registration.addUrlPatterns("/*");        registration.setName("corsFilter");        return registration;    }

参考博文:

https://blog.coding.net/blog/spring-mvc-cors

最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台