Controller注解@CrossOrigin,解决跨域问题

十点数据 1年前 ⋅ 4165 阅读

跨域错误.png

一、关于跨域介绍

什么是跨域问题?

跨域问题来源于JavaScript的"同源策略",即只有 协议+主机名+端口号 (如存在)相同,则允许相互访问。也就是说JavaScript只能访问和操作自己域下的资源,不能访问和操作其他域下的资源。跨域问题是针对JS和ajax的,html本身没有跨域问题。

在前后分离的架构下,跨域问题难免会遇见比如,站点 http://domain-a.com 的某 HTML 页面通过 的 src 请求 http://domain-b.com/image.jpg。网络上的许多页面都会加载来自不同域的CSS样式表,图像和脚本等资源。

出于安全原因,浏览器限制从脚本内发起的跨源HTTP请求。 例如,XMLHttpRequest和Fetch API遵循同源策略。 这意味着使用这些API的Web应用程序只能从加载应用程序的同一个域请求HTTP资源,除非使用CORS头文件。

跨域的体现,在于它的域名不同或者端口不同,但要注意以下的形式为非跨域模式 http://www.example.com/index.html ==> http://www.example.com/login.html

二、Spring Boot跨域(@CrossOrigin)

当然这里虽然指SpringBoot但是SpringMVC也是一样的,要求在Spring4.2及以上的版本

1、@CrossOrigin使用场景要求

jdk1.8+ Spring4.2+

2、@CrossOrigin源码解析(翻译参考网络)

@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CrossOrigin {
	String[] DEFAULT_ORIGINS = { "*" };
	String[] DEFAULT_ALLOWED_HEADERS = { "*" };
 boolean DEFAULT_ALLOW_CREDENTIALS = true;
	long DEFAULT_MAX_AGE = 1800;
	/**
	 * 同origins属性一样
	 */
	@AliasFor("origins")
	String[] value() default {};
 /**
	 * 所有支持域的集合,例如"http://domain1.com"。
	 * <p>这些值都显示在请求头中的Access-Control-Allow-Origin
	 * "*"代表所有域的请求都支持
 	* <p>如果没有定义,所有请求的域都支持
 	* @see #value
 	*/
 @AliasFor("value")
 String[] origins() default {};
	/**
	 * 允许请求头重的header,默认都支持
	 */
 String[] allowedHeaders() default {};
	/**
	 * 响应头中允许访问的header,默认为空
 	*/
 String[] exposedHeaders() default {};

	/**
	 * 请求支持的方法,例如"{RequestMethod.GET, RequestMethod.POST}"}。
	 * 默认支持RequestMapping中设置的方法
	 */
	RequestMethod[] methods() default {};
 /**
	 * 是否允许cookie随请求发送,使用时必须指定具体的域
	 */
 String allowCredentials() default "";
	/**
	 * 预请求的结果的有效期,默认30分钟
 	*/
	long maxAge() default -1;
} 

3、@CrossOrigin使用

SpringBoot下的请求处理控制器

//实现跨域注解
//origin="*"代表所有域名都可访问
//maxAge飞行前响应的缓存持续时间的最大年龄,简单来说就是Cookie的有效期 单位为秒
//若maxAge是负数,则代表为临时Cookie,不会被持久化,Cookie信息保存在浏览器内存中,浏览器关闭Cookie就消失
@CrossOrigin(origins = "*",maxAge = 3600)
@RestController
@RequestMapping("/crawler")
public class CrawlerController {
 	 
	@RequestMapping(value = "/fetchGroupMonthCrawlerStat", method = 		
    RequestMethod.GET, produces = {
		"application/json;charSet=UTF-8" })
	public String fetchGroupMonthCrawlerStat(HttpServletResponse response, 
    HttpServletRequest request) {
		//处理业务逻辑,并返回数据;
	}
}

全部评论: 0

    我有话说: