跨域问题-cors

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_38704338/article/details/79353864

package myggirl.wangpan.config;  
import org.springframework.boot.web.servlet.FilterRegistrationBean;  
import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
import org.springframework.util.StringUtils;  
  
import javax.servlet.*;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
import java.io.IOException;  
  
/** 
 * 解决跨域问题 
 */  
  
@Configuration  
public class FilterConfig {  
    @Bean  
    public RemoteIpFilter remoteIpFilter() {  
        return new RemoteIpFilter();  
    }  
  
    @Bean  
    public FilterRegistrationBean testFilterRegistration() {  
        FilterRegistrationBean registration = new FilterRegistrationBean();  
        registration.setFilter(new MyFilter());//添加过滤器  
        registration.addUrlPatterns("/*");//设置过滤路径,/*所有路径  
        registration.addInitParameter("name", "alue");//添加默认参数  
        registration.setName("MyFilter");//设置优先级  
        registration.setOrder(1);//设置优先级  
        return registration;  
    }  
  
    public class MyFilter implements Filter {  
        @Override  
        public void destroy() {  
        }  
  
        @Override  
        public void init(javax.servlet.FilterConfig filterConfig) throws ServletException {  
            System.out.println("初始化了");  
        }  
  
        @Override  
        public void doFilter(ServletRequest srequest, ServletResponse sresponse, FilterChain  
                filterChain)  
                throws IOException, ServletException {  
            HttpServletRequest request = (HttpServletRequest) srequest;  
            HttpServletResponse response = (HttpServletResponse) sresponse;  
  
            String origin = request.getHeader("Origin");  
            String headers = request.getHeader("Access-Control-Request-Headers");  
            //支持跨域的域名,origin的值为跨域的域名。  
            if(!StringUtils.isEmpty(origin)) {  
                response.addHeader("Access-Control-Allow-Origin",origin);  
            }  
            //支持自定义头的跨域请求  
            if(!StringUtils.isEmpty(headers)) {  
                response.addHeader("Access-Control-Allow-Headers",headers);  
            }  
            //cookie跨域时不能用*。  
            //response.addHeader("Access-Control-Allow-Origin","*");  
            response.addHeader("Access-Control-Allow-Methods","*");  
            response.addHeader("Access-Control-Max-Age","3600");预检命令缓存时间,这段时间里不再发送域检命令。  
            //enable cookie  
            response.addHeader("Access-Control-Allow-Credentials","true");  
  
            //打印请求Url  
            System.out.println("过滤器过滤的,url :" + request.getRequestURI());  
            filterChain.doFilter(srequest, sresponse);  
        }  
  
  
    }  
}  

两种请求

    浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。

 非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,请求方法是OPTIONS,称为"预检"请求(preflight)。

非简单请求:比如请求方法是PUTDELETE,或者Content-Type字段的类型是application/json,或者加入自定义请求头。

预检请求

   浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。 

"预检"请求用的请求方法是OPTIONS,表示这个请求是用来询问的。头信息里面,关键字段是Origin,表示请求来自哪个源。

除了Origin字段(请求头中会有一个origin字段,含义是发起请求的所在域名)。

(1)Access-Control-Request-Method

该字段是必须的,用来列出浏览器的CORS请求会用到哪些HTTP方法。

(2)Access-Control-Request-Headers

该字段是一个逗号分隔的字符串,指定浏览器CORS请求会额外发送的头信息字段。

(3)Access-Control-Allow-Origin

该字段是一个逗号分隔的字符串,指定浏览器CORS请求允许的域名。

(4)Access-Control-Max-Age

该字段可选,用来指定本次预检请求的有效期,单位为秒。上面结果中,有效期是20天(1728000秒),即允许缓存该条回应1728000秒(即20天),在此期间,不用发出另一条预检请求。

(5)Access-Control-Allow-Credentials

该字段可选。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。

withCredentials 属性

上面说到,CORS请求默认不发送Cookie和HTTP认证信息。如果要把Cookie发到服务器,一方面要服务器同意,指定Access-Control-Allow-Credentials字段。

Access-Control-Allow-Credentials: true

另一方面,开发者必须在AJAX请求中打开withCredentials属性。

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

否则,即使服务器同意发送Cookie,浏览器也不会发送。或者,服务器要求设置Cookie,浏览器也不会处理。

猜你喜欢

转载自blog.csdn.net/weixin_38704338/article/details/79353864