zoukankan      html  css  js  c++  java
  • Halo(九)

    跨域问题

    域名A(http://www.a.com)的 Web 应用程序中,
    通过标签引入了域名B(http://ww.b.com)站点的某图片资源(http://www.b.com/image.jpg),
    域名A的 Web 应用就会导致浏览器发起一个跨域 HTTP 请求。
    
    
    同源策略:
    	不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。
    	一个请求地址里面的协议、域名和端口号都相同,就属于同源。
    
    
    不允许跨域访问的网站无法跨域访问(由于同源策略)。
    

    CORS(Cross-Origin Resource Sharing)解决跨域请求问题

    CORS基本思想:
    	使用自定义的HTTP请求头使浏览器和服务器相互了解对方,从而决定请求或响应成功与否。
    
    
    CORS分为简单请求和非简单请求(需预检请求)两类:
    
    	简单请求
    
    		请求方式使用下列方法之一:
    			GET
    			HEAD
    			POST
     
     		HTTP的头信息不超出以下几种字段 
    			1. Accept
    			2. Accept-Language
    			3. Content-Language
    			4. Last-Event-ID
    			5. Content-Type 的值仅限于下列三者之一:
    				text/plain
    				multipart/form-data
    				application/x-www-form-urlencoded
    
    		对于简单请求,浏览器会直接发送CORS请求
    			请求头字段header中加入:origin
    			响应头字段header中加入:
    				Access-Control-Allow-Origin:可跨域的源
    				Access-Control-Allow-Credentials:是否允许用户发送、处理 cookie(可选)
    
    	非简单请求(除了简单请求,其他都是非简单请求)
    
    		使用了下面任一 HTTP 方法:
    			PUT
    			DELETE
    			CONNECT
    			OPTIONS
    			TRACE
    			PATCH
     
    		Content-Type 的值不属于下列之一:
    			application/x-www-form-urlencoded
    			multipart/form-data
    			text/plain
    
    		浏览器会先发送预检请求(不会携带Cookie和传递的参数),发送一次Preflight Request,接收一个Preflight Response。
    		预检请求判断是否允许跨域访问后,才决定是否发送真正的请求。
    
    		非简单请求会在头部多返回以下字:
    			请求头:origin
    			响应头:
    				Access-Control-Allow-Origin:可跨域的资源路径
    				Access-Control-Allow-Methods:服务端支持的请求方法
    				Access-Control-Allow-Headers:服务器允许使用的字段
    				Access-Control-Allow-Credentials:是否允许用户发送、处理 cookie
    				Access-Control-Max-Age:预检请求的有效期,单位为秒。有效期内,不会重复发送预检请求
    

    Spring Boot CORS 实现

    局部:
    	Controller类上使用(对该类所有方法有效):@CrossOrigin
    	Controller方法上使用:@CrossOrigin
    
    
    全局:
    	使用配置类实现
    
    方法1. 添加一个配置类
    
    @Configuration
    public class CorsConfig extends WebMvcConfigurerAdapter {
    
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")	//允许跨域访问的路径
                    .allowedOrigins("*")	//允许跨域访问的资源路径
                    .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")	//允许请求方法
                    .allowedHeaders("Content-Type", "ADMIN-Authorization")	//
                    .maxAge(3600)	//预检间隔时间
                    .allowCredentials(true);	//是否允许发送cookie
        }
    }
    
    方法2. 添加一个过滤器
    
    public class CorsFilter extends GenericFilterBean {
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            HttpServletRequest httpServletRequest = (HttpServletRequest) request;
            HttpServletResponse httpServletResponse = (HttpServletResponse) response;
    
            /** 设置自定义头 */
            httpServletResponse.setHeader("Access-Control-Allow-Origin", httpServletRequest.getHeader(HttpHeaders.ORIGIN));
            httpServletResponse.setHeader("Access-Control-Allow-Headers", "Content-Type, ADMIN-Authorization");
            httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
            httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
            httpServletResponse.setHeader("Access-Control-Max-Age", "3600");
    
            //非预检请求,给予通过(预检请求直接返回响应头)
            if (!CorsUtils.isPreFlightRequest(httpServletRequest)) {
                chain.doFilter(httpServletRequest, httpServletResponse);
            }
        }
    }
    
    @Configuration
    public class HaloConfiguration {
        @Bean
        public FilterRegistrationBean<CorsFilter> corsFilter() {
            FilterRegistrationBean<CorsFilter> corsFilter = new FilterRegistrationBean<>();
            //设置优先级
            corsFilter.setOrder(Ordered.HIGHEST_PRECEDENCE);
            corsFilter.setFilter(new CorsFilter());
            corsFilter.addUrlPatterns("/api/*");
            return corsFilter;
        }
    }
    
  • 相关阅读:
    Informatica 常用组件Lookup缓存之五 使用动态查找高速缓存
    Informatica 常用组件Lookup缓存之四 使用不高速缓存的查找或静态高速缓存
    Informatica 常用组件Lookup缓存之三 重建查找高速缓存
    Golang入门教程(十一)beego 框架之RESTful Controller 路由
    PHP7 学习笔记(十二)PHPExcel vs PhpSpreadsheet and PHP_XLSXWriter
    PHP7 学习笔记(十二)gRPC
    PHP7 学习笔记(十一)使用phpstudy快速配置一个虚拟主机
    Golang入门教程(十)内建函数
    Golang入门教程(九)复合数据类型使用案例二
    Golang入门教程(八)复合数据类型使用案例一
  • 原文地址:https://www.cnblogs.com/loveer/p/11942327.html
Copyright © 2011-2022 走看看