首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

遇上浏览器跨域问题怎么办?

  • 24-03-05 01:20
  • 3252
  • 5175
blog.csdn.net

640?wx_fmt=gif

640?wx_fmt=jpeg

出于安全原因,浏览器禁止 Ajax 调用驻留在当前原点之外的资源。例如,当你在一个标签中检查你的银行账户时,你可以在另一个选项卡上拥有 EVILL 网站。来自 EVILL 的脚本不能够对你的银行 API 做出 Ajax 请求(从你的帐户中取出钱!)使用您的凭据。

跨源资源共享(CORS)是由大多数浏览器实现的 W3C 规范,允许你灵活地指定什么样的跨域请求被授权,而不是使用一些不太安全和不太强大的策略,如 IFRAME 或 JSONP。


640?wx_fmt=png

跨域(CORS)支持


Spring Framework 4.2 GA 为 CORS 提供了第一类支持,使您比通常的基于过滤器的解决方案更容易和更强大地配置它。所以 springMVC 的版本要在 4.2 或以上版本才支持 @CrossOrigin


640?wx_fmt=png

使用方法


1. controller 配置 CORS

1.1 controller 方法的 CORS 配置,您可以向 @RequestMapping 注解处理程序方法添加一个 @CrossOrigin 注解,以便启用 CORS(默认情况下,@CrossOrigin 允许在 @RequestMapping 注解中指定的所有源和 HTTP 方法):

 
 

@RestController
@RequestMapping("/account")
public class AccountController {
   @CrossOrigin
   @GetMapping("/{id}")
   public Account retrieve(@PathVariable Long id) {
       // ...
   }
   @DeleteMapping("/{id}")
   public void remove(@PathVariable Long id) {
       // ...
   }
}

其中 @CrossOrigin 中的 2 个参数:

  • origins : 允许可访问的域列表

  • maxAge:准备响应前的缓存持续的最大时间(以秒为单位)。

1.2 为整个 controller 启用 @CrossOrigin

 
 

@CrossOrigin(origins = "http://domain2.com", maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {
   @GetMapping("/{id}")
   public Account retrieve(@PathVariable Long id) {
       // ...
   }
   @DeleteMapping("/{id}")
   public void remove(@PathVariable Long id) {
       // ...
   }
}

在这个例子中,对于 retrieve() 和 remove() 处理方法都启用了跨域支持,还可以看到如何使用 @CrossOrigin 属性定制 CORS 配置。

1.3 同时使用 controller 和方法级别的 CORS 配置,Spring 将合并两个注释属性以创建合并的 CORS 配置。

 
 

@CrossOrigin(maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {
   @CrossOrigin(origins = "http://domain2.com")
   @GetMapping("/{id}")
   public Account retrieve(@PathVariable Long id) {
       // ...
   }
   @DeleteMapping("/{id}")
   public void remove(@PathVariable Long id) {
       // ...
   }
}

1.4 如果您正在使用 Spring Security,请确保在 Spring 安全级别启用 CORS,并允许它利用 Spring MVC 级别定义的配置。

 
 

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
   @Override
   protected void configure(HttpSecurity http) throws Exception {
       http.cors().and()...
   }
}

2. 全局 CORS 配置

除了细粒度、基于注释的配置之外,您还可能需要定义一些全局 CORS 配置。这类似于使用筛选器,但可以声明为 Spring MVC 并结合细粒度 @CrossOrigin 配置。默认情况下,所有 origins and GET, HEAD and POST methods 是允许的。

JavaConfig

使整个应用程序的 CORS 简化为:

 
 

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
   @Override
   public void addCorsMappings(CorsRegistry registry) {
       registry.addMapping("/**");
   }
}

如果您正在使用 Spring Boot,建议将 WebMvcConfigurer bean 声明如下:

 
 

@Configuration
public class MyConfiguration {
   @Bean
   public WebMvcConfigurer corsConfigurer() {
       return new WebMvcConfigurerAdapter() {
           @Override
           public void addCorsMappings(CorsRegistry registry) {
               registry.addMapping("/**");
           }
       };
   }
}

您可以轻松地更改任何属性,以及仅将此 CORS 配置应用到特定的路径模式:

 
 

@Override
public void addCorsMappings(CorsRegistry registry) {
   registry.addMapping("/api/**")
       .allowedOrigins("http://domain2.com")
       .allowedMethods("PUT", "DELETE")
           .allowedHeaders("header1", "header2", "header3")
       .exposedHeaders("header1", "header2")
       .allowCredentials(false).maxAge(3600);
}

如果您正在使用 Spring Security,请确保在 Spring 安全级别启用 CORS,并允许它利用 Spring MVC 级别定义的配置。

3. XML命名空间

还可以将 CORS 与 MVC XML 命名空间配置。

a) 如果整个项目所有方法都可以访问,则可以这样配置;此最小 XML 配置使 CORS 在 /** 路径模式具有与 JavaConfig 相同的缺省属性:

 
 

<mvc:cors>
   <mvc:mapping path="/**" />
mvc:cors>

其中 * 表示匹配到下一层;** 表示后面不管有多少层,都能匹配。

如:

 
 

<mvc:cors>  
   <mvc:mapping path="/api/*"/>  
mvc:cors>  

这个可以匹配到的路径有:

/api/aaa

/api/bbbb

不能匹配的:

/api/aaa/bbb

因为 * 只能匹配到下一层路径,如果想后面不管多少层都可以匹配,配置如下:

 
 

<mvc:cors>  
   <mvc:mapping path="/api/**"/>  
mvc:cors>  

注:其实就是一个 () 变成两个 (*)

b) 也可以用定制属性声明几个 CORS 映射:

 
 

<mvc:cors>
   <mvc:mapping path="/api/**"
       allowed-origins="http://domain1.com, http://domain2.com"
       allowed-methods="GET, PUT"
       allowed-headers="header1, header2, header3"
       exposed-headers="header1, header2" allow-credentials="false"
       max-age="123" />

   <mvc:mapping path="/resources/**"
       allowed-origins="http://domain1.com" />

mvc:cors>

请求路径有 /api/,方法示例如下:

 
 

@RequestMapping("/api/crossDomain")  
@ResponseBody  
public String crossDomain(HttpServletRequest req, HttpServletResponse res, String name){  
   ……  
   ……  
}

c) 如果使用 Spring Security,不要忘记在 Spring 安全级别启用 CORS:

 
 

<http>
   
   <cors />
   ...
http>

4. How does it work?

CORS 请求(包括预选的带有选项方法)被自动发送到注册的各种 HandlerMapping 。它们处理 CORS 准备请求并拦截 CORS 简单和实际请求,这得益于 CorsProcessor 实现(默认情况下默认 DefaultCorsProcessor 处理器),以便添加相关的 CORS 响应头(如 Access-Control-Allow-Origin)。 CorsConfiguration 允许您指定 CORS 请求应该如何处理:允许 origins, headers, methods 等。

a) AbstractHandlerMapping 类的 setCorsConfiguration() 方法允许指定一个映射,其中有几个 CorsConfiguration 映射在路径模式上,比如 /api/**。

b) 子类可以通过重写 AbstractHandlerMapping 类的 getCorsConfiguration(Object, HttpServletRequest) 方法来提供自己的 CorsConfiguration。

c) 处理程序可以实现 CorsConfigurationSource 接口(如 ResourceHttpRequestHandler),以便为每个请求提供一个 CorsConfiguration。

5. 基于过滤器的 CORS 支持

作为上述其他方法的替代,Spring 框架还提供了 CorsFilter。在这种情况下,不用使用 @CrossOrigin 或 WebMvcConfigurer#addCorsMappings(CorsRegistry),例如,可以在 Spring Boot 应用程序中声明如下的过滤器:

 
 

@Configuration
public class MyConfiguration {
   @Bean
   public FilterRegistrationBean corsFilter() {
       UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
       CorsConfiguration config = new CorsConfiguration();
       config.setAllowCredentials(true);
       config.addAllowedOrigin("http://domain1.com");
       config.addAllowedHeader("*");
       config.addAllowedMethod("*");
       source.registerCorsConfiguration("/**", config);
       FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
       bean.setOrder(0);
       return bean;
   }
}


640?wx_fmt=png

spring 注解 @CrossOrigin 不起作用的原因


1. 是 springMVC 的版本要在 4.2 或以上版本才支持 @CrossOrigin

2. 非 @CrossOrigin 没有解决跨域请求问题,而是不正确的请求导致无法得到预期的响应,导致浏览器端提示跨域问题。

3. 在 Controller 注解上方添加 @CrossOrigin 注解后,仍然出现跨域问题,解决方案之一就是:

在 @RequestMapping 注解中没有指定 Get、Post 方式,具体指定后,问题解决。

类似代码如下:

 
 

@CrossOrigin
@RestController
public class person{
   @RequestMapping(method = RequestMethod.GET)
   public String add() {
       // 若干代码
   }
}

参考文章:

1. 官方文档 https://spring.io/blog/2015/06/08/cors-support-in-spring-framework
2. http://fanshuyao.iteye.com/blog/2384189
3. https://blog.csdn.net/taiyangnimeide/article/details/78305131
4. https://blog.csdn.net/snowin1994/article/details/53035433

作者:淼淼之森 ,一个码在第一线的JAVA开发者 。

声明:本文为作者投稿,版权归对方所有。



 热 文 推 荐 

☞ 华为很好,但我不愿再回去

☞ 背靠 Google 的 Go 语言,就不会失败?

☞ 你是否真的懂数组?

无业务不技术:那些誓用区块链重塑的行业,发展怎么样了?

☞ 下一次 IT 变革:边缘计算(Edge computing)

☞ 12306 脱库 410 万用户数据究竟从何泄漏?

年度重磅:《AI聚变:2018年优秀AI应用案例TOP 20》正式发布

☞ 老程序员肺腑忠告:千万别一辈子靠技术生存!

 
 

print_r('点个好看吧!');
var_dump('点个好看吧!');
NSLog(@"点个好看吧!");
System.out.println("点个好看吧!");
console.log("点个好看吧!");
print("点个好看吧!");
printf("点个好看吧! ");
cout << "点个好看吧!" << endl;
Console.WriteLine("点个好看吧!");
fmt.Println("点个好看吧!");
Response.Write("点个好看吧!");
alert("点个好看吧!")
echo "点个好看吧!"

640?wx_fmt=gif点击“阅读原文”,打开 CSDN App 阅读更贴心!

640?wx_fmt=png 喜欢就点击“好看”吧!
CSDN
微信公众号
成就一亿技术人
注:本文转载自blog.csdn.net的CSDN资讯的文章"https://blog.csdn.net/csdnnews/article/details/85522664"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top