CORS跨域资源共享处理

什么是跨域?

当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域。
出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)

跨域解决方法

01、定义CorsFilter处理

Spring MVC 4.2后内置了一个CorsFilter专门用于处理CORS请求问题,它所在的路径是:org.springframework.web.filter.CorsFilter。通过配置这个Filter使它生效便可统一控制跨域请求(URL级别控制)推荐使用

package com.qd.common;

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;

/**
 * 跨域处理
 *
 * @Author: qiandu
 * @Blog: https://www.cnblogs.com/qd666
 * @Date: 2021/11/13
 */
@Configuration
public class CorsConfig {

    // 当前跨域请求最大有效时长。这里默认1天
    private static final long MAX_AGE = 24 * 60 * 60;

    private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址
        corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头
        corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法
        corsConfiguration.setMaxAge(MAX_AGE);
        return corsConfiguration;
    }

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", buildConfig()); // 4 对接口配置跨域设置
        return new CorsFilter(source);
    }
}

02、使用注解@CrossOrigin

如果觉得使用CorsFilter配置起来麻烦,或者你想实现精细化且更加简便的控制,那么@CrossOrigin这个注解你值得拥有。
它可以使用在类上也可以使用在方法上,使用方式极其简单,如下案例:

   /**
    * 根据id查询数据
    *
    * @param id
    * @return
    */
   @GetMapping("/{id}")
   @CrossOrigin
   public User findById(@PathVariable long id) {
       return userService.getById(id);
   }

03、Nginx统一配置

配置在Nginx后,后端服务就不用再操心跨域请求问题了,这是很多公司推荐的方案。 推荐使用

#
# Wide-open CORS config for nginx
#
location / {
	
	#### 对OPTIONS请求,会设置很多的请求头,并返回204
     if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        #
        # Custom headers and headers various browsers *should* be OK with but aren't
        #
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        #
        # Tell client that this pre-flight info is valid for 20 days
        #
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain; charset=utf-8';
        add_header 'Content-Length' 0;
        return 204;
     }
     if ($request_method = 'POST') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
     }
     if ($request_method = 'GET') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
     }
}

04、自定义Filter/HandlerInterceptor

// 自定义一个Filter来处理CORS跨域请求
@Component
public class CORSFilter implements Filter {
  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
  }

  // TODO:这里应该是只需要处理OPTIONS请求即可~~~
  @Override
  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    	HttpServletResponse response = (HttpServletResponse) servletResponse;
    	response.setHeader("Access-Control-Allow-Origin", "*");
    	response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
    	response.setHeader("Access-Control-Max-Age", "3600");
    	response.setHeader("Access-Control-Allow-Headers", "content-type,Authorization");
    	// response.setHeader("Access-Control-Allow-Credentials", "true");
    	filterChain.doFilter(servletRequest, servletResponse);
  }

  @Override
  public void destroy() {
  }
}

参考文章:

https://chttps://cloud.tencent.com/developer/article/1513473loud.tencent.com/developer/article/1513473

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值