SpringBoot解决跨域的三种方式

1. 简介

  随着现在前后端分离项目愈发普及,面临第一步的问题即为跨域。一般的URL地址(例如:https://www.cnblogs.com/cao-lei/)由协议 + 域名(子域名 + 主域名) + 端口号 + 资源地址组成,当协议、域名(子域名 + 主域名)、端口号这三项中有一项不同,则认为为不同的域,不同的域互相请求资源,即为跨域。
  为了解决这一问题,需要引入CORS(Cross-origin resource sharing)跨域资源共享。它允许浏览器向跨域服务器发送请求,当浏览器发现此次请求时跨域时会在请求头添加一些附加信息,但这些改变对于用户是无感知的。
  当发送CORS请求时,会先发送一次OPTIONS预请求,服务端接收到预请求时会检测本次请求是否在许可名单中,若允许才会发送正式请求,否则报错。

2. 响应头解释

响应头 解释
Access-Control-Allow-Origin 允许的域名。为空则不允许任何域名,为*则允许任何域名,也可指定具体域名,例如:http://www.C3Stones.com
Access-Control-Allow-Methods 允许的方法类型。为空则不允许任何类型,为*则允许任何类型,也可指定类型,例如:GET, POST, PUT, DELETE, OPTIONS, HEAD。
Access-Control-Allow-Headers 允许的标头。为空则不允许任何标头,为*则允许任何标头,也可指定标头,例如:Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With。
Access-Control-Allow-Credentials 是否允许接收跨域的Cookie凭证数据。默认为false,当PUT请求或者DELETE请求或者Content-Type为application/json时,设置为true。一般为了方便,设置为true。
Access-Control-Max-Age 预检请求的有效期,单位为秒。在有效期内不用再发预检请求。

3. 添加CORS配置类解决

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * Cors配置类
 * 
 * @author CL
 *
 */
@Configuration
public class CorsConfig implements WebMvcConfigurer {

	/**
	 * 配置跨域请求处理
	 * 
	 * @param registry Cors注册类
	 */
	@Override
	public void addCorsMappings(CorsRegistry registry) {
		registry
			.addMapping("/**")
			.allowedOrigins("*")
			.allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
			.allowedHeaders("Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With")
			.allowCredentials(true)
			.maxAge(3600);
	}

}

4. 配置CORS过滤器解决

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.annotation.Configuration;

/**
 * Cors过滤器
 * 
 * @author CL
 *
 */
@Configuration
@WebFilter(filterName = "CorsFilter")
public class CorsFilter implements Filter {

	/**
	 * 过滤
	 */
	@Override
	public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
			throws IOException, ServletException {
		HttpServletResponse response = (HttpServletResponse) res;
		response.setHeader("Access-Control-Allow-Origin", "*");
		response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
		response.setHeader("Access-Control-Allow-Headers", "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With");
		response.setHeader("Access-Control-Allow-Credentials", "true");
		response.setHeader("Access-Control-Max-Age", "3600");
		chain.doFilter(req, res);
	}
	
}

5. 注解CrossOrigin解决

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * Cors示例Controller
 * 
 * @author Administrator
 *
 */
@CrossOrigin(origins = "http://www.C3Stones.com")
@Controller
@RequestMapping(value = "/cors/demo")
public class CorsDemoController {

	/**
	 * 示例方法
	 * 
	 * @return
	 */
	@CrossOrigin(origins = "http://www.C3Stones.com", 
			methods = { RequestMethod.OPTIONS, RequestMethod.GET }, 
			maxAge = 3600)
	@RequestMapping(value = "hello")
	@ResponseBody
	public String hello() {
		return "Hello World!";
	}

}
posted @ 2021-04-01 21:37  C3Stones  阅读(606)  评论(0编辑  收藏  举报