1、什么是跨域

由于浏览器同源策略(同源策略,它是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。),凡是发送请求url的协议、域名、端口三者之间任意一与当前页面地址不同即为跨域。

具体可以查看下表:

2、springboot如何解决跨域问题

1.普通跨域请求解决方案:

①请求接口添加注解@CrossOrigin(origins = "http://127.0.0.1:8020", maxAge = 3600)

说明:origins = "http://127.0.0.1:8020" origins值为当前请求该接口的域

②通用配置(所有接口都允许跨域请求)

新增一个configration类 或 在Application中加入CorsFilter和CorsConfiguration方法

  1. @Configuration
  2. public class CorsConfig {
  3. private CorsConfiguration buildConfig() {
  4. CorsConfiguration corsConfiguration = new CorsConfiguration();
  5. corsConfiguration.addAllowedOrigin("*"); // 1允许任何域名使用
  6. corsConfiguration.addAllowedHeader("*"); // 2允许任何头
  7. corsConfiguration.addAllowedMethod("*"); // 3允许任何方法(post、get等)
  8. return corsConfiguration;
  9. }
  10.  
  11. @Bean
  12. public CorsFilter corsFilter() {
  13. UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
  14. source.registerCorsConfiguration("/**", buildConfig()); // 4
  15. return new CorsFilter(source);
  16. }
  17. }
  1.  

2.ajax自定义headers的跨域请求

  1. $.ajax({
  2. type:"GET",
  3. url:"http://localhost:8766/main/currency/sginInState",
  4. dataType:"JSON",
  5. data:{
  6. uid:userId
  7. },
  8. beforeSend: function (XMLHttpRequest) {
  9. XMLHttpRequest.setRequestHeader("Authorization", access_token);
  10. },
  11. success:function(res){
  12. console.log(res.code)
  13. }
  14. })
  1.  

此时请求http://localhost:8766/main/currency/sginInState接口发现OPTIONS http://localhost:8766/main/currency/sginInState 500错误,普通跨域的解决方案已经无法解决这种问题,为什么会出现OPTIONS请求呢?

原因

浏览器会在发送真正请求之前,先发送一个方法为OPTIONS的预检请求 Preflighted requests 这个请求是用来验证本次请求是否安全的,但是并不是所有请求都会发送,需要符合以下条件:

  • 请求方法不是GET/HEAD/POST

  • POST请求的Content-Type并非application/x-www-form-urlencoded, multipart/form-data, 或text/plain

  • 请求设置了自定义的header字段

对于管理端的接口,我有对接口进行权限校验,每次请求需要在header中携带自定义的字段(token),所以浏览器会多发送一个OPTIONS请求去验证此次请求的安全性。

为何OPTIONS请求是500呢?

OPTIONS请求只会携带自定义的字段,并不会将相应的值带入进去,而后台校验token字段时 token为NULL,所以验证不通过,抛出了一个异常。

那么我们现在来解决这种问题:

① spring boot项目application.yml中添加

  1. spring:
  2. mvc:
  3. dispatch-options-request: true

注意:这种解决方案可能在某些情况下并不能解决OPTIONS问题,原因可能是环境问题,也可能是复杂的自定义filter过滤器配置问题等。

②添加过滤器配置

第一步:手写RequestFilter请求过滤器配置类此类需要实现HandlerInterceptor类,HandlerInterceptor类是org.springframework.web.servlet.HandlerInterceptor下的。

具体代码实现:

  1. @Component
  2. public class RequestFilter implements HandlerInterceptor {
  3. public boolean preHandler(HttpServletRequest request,HttpServletResponse response,Object handler){
  4. response.setHeader("Access-Control-Allow-Origin", "*");
  5. response.setHeader("Access-Control-Allow-Credentials", "true");
  6. response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS");
  7. response.setHeader("Access-Control-Max-Age", "86400");
  8. response.setHeader("Access-Control-Allow-Headers", "Authorization");
  9. // 如果是OPTIONS请求则结束
  10. if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) {
  11. response.setStatus(HttpStatus.NO_CONTENT.value());
  12. return false;
  13. }
  14. return true;
  15. }
  16. }
  1.  

第二步:手写MyWebConfiguration此类需要继承WebMvcConfigurationSupport。

注意:WebMvcConfigurationSupport是2.x版本以上的,1.x版本为WebMvcConfigurerAdapter 。

具体代码实现:

  1. @Component
  2. public class MyWebConfiguration extends WebMvcConfigurationSupport{
  3. @Resource
  4. private RequestFilter requestFilter;
  5. @Override
  6. public void addInterceptors(InterceptorRegistry registry) {
  7. // 跨域拦截器
  8. registry.addInterceptor(requestFilter).addPathPatterns("/**");
  9. }
  10. }

此时我们就完美解决了ajax+自定义headers的跨域请求了,欢迎随时交流学习。

Springboot如何优雅的解决ajax+自定义headers的跨域请求[转]的更多相关文章

  1. Springboot如何优雅的解决ajax+自定义headers的跨域请求

    1.什么是跨域 由于浏览器同源策略(同源策略,它是由Netscape提出的一个著名的安全策略.现在所有支持JavaScript 的浏览器都会使用这个策略.所谓同源是指,域名,协议,端口相同.),凡是发 ...

  2. Ajax+Spring MVC实现跨域请求(JSONP)(转)

    背景: AJAX向后台(springmvc)发送请求,报错:已阻止交叉源请求:同源策略不允许读取 http://127.0.0.1:8080/DevInfoWeb/getJsonp 上的远程资源.可 ...

  3. Ajax+Spring MVC实现跨域请求(JSONP)

    背景: AJAX向后台(springmvc)发送请求,报错:已阻止交叉源请求:同源策略不允许读取 http://127.0.0.1:8080/DevInfoWeb/getJsonp 上的远程资源.可 ...

  4. Ajax+Spring MVC实现跨域请求(JSONP)JSONP 跨域

    JSONP原理及实现 接下来,来实际模拟一个跨域请求的解决方案.后端为Spring MVC架构的,前端则通过Ajax进行跨域访问. 1.首先客户端需要注册一个callback(服务端通过该callba ...

  5. 20191204-使用nginx解决ajax测试调用接口跨域问题

    问题描述 之前要测试一个http的接口,在postman中测试成功,但使用ajax调用却跨域.于是通过使用ngin反向代理的方式来解决ajax调用跨域问题 测试页面的内容 <html> & ...

  6. Ajax操作如何实现跨域请求 (JSONP和CORS实现Ajax跨域的原理)

    由于浏览器存在同源策略机制,同源策略阻止ajax (XMLHttpRequest) 从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性. 特别的:由于同源策略是浏览器的限制,所以请求的发送和响 ...

  7. jQuery Ajax 简单的实现跨域请求

    html 代码清单: <script type="text/javascript" src="http://www.youxiaju.com/js/jquery-1 ...

  8. ajax发送多个跨域请求回调不混乱

    var count = 0; var codes = ""; function refreshCache(urls){ try { var url = urls.split(&qu ...

  9. 解决asp.net mvc的跨域请求问题

    web.config中配置如下内容: <system.webServer> <httpProtocol> <customHeaders> <add name= ...

随机推荐

  1. quartz2.3.0(十二)通过RMI协议向Scheduler调度器远程添加job任务

    此代码示例通过RMI协议向Scheduler调度器远程添加job任务. 代码文件包括:job任务类(SimpleJob.java).RMI服务端server类(RemoteServerExample. ...

  2. [高清] SpringBoot揭秘快速构建微服务体系

    ------ 郑重声明 --------- 资源来自网络,纯粹共享交流, 如果喜欢,请您务必支持正版!! --------------------------------------------- 下 ...

  3. Windows服务创建及发布

    二.创建Windows Service 1.新建一个Windows Service,并将项目名称改为“MyWindowsService”,如下图所示: 2.在解决方案资源管理器内将Service1.c ...

  4. 数据结构与算法(周测9-B树与B+树)

    由于博主太菜,题目集还不完整,有待更新. 判断题 1.m阶B树的根结点最多有m棵子树.      T      F 2.In a B+ tree, leaves and nonleaf nodes h ...

  5. iOS - WWDC18 iOS 自动生成强密码和自动填充验证码/密码

    本文将介绍WWDC18 Automatic Strong Passwords and Security Code Autofill和WWDC17 Introducing Password AutoFi ...

  6. viewer 图片点击放大 用法汇总

    A 不用viewer插件 1弹出框 https://www.cnblogs.com/web1/p/8989967.html 2表格中 https://www.jianshu.com/p/c17f4f6 ...

  7. vi / vim 基本操作

    进入vi的命令         vi filename :打开或新建文件,并将光标置于第一行首    vi n filename :打开文件,并将光标置于第n行首    vi filename :打开 ...

  8. 【MySQL】你以为设置了并行复制就降低延迟了?这个你绝对想不到!

    在MySQL官方版本中,为了保证其的高可用性,一般情况我们会采用主从复制的方式来解决.当然,方法很多.而我们今天所要处理的是采用GTID方式并且开了多线程复制后,仍然延迟的情况,糟糕的是,延迟还在不断 ...

  9. ViewBag---MVC3中 ViewBag、ViewData和TempData的使用和差别-------与ViewBag+Hashtable应用例子

    ViewBag 在MVC3開始.视图数据能够通过ViewBag属性訪问.在MVC2中则是使用ViewData.MVC3中保留了ViewData的使用.ViewBag 是动态类型(dynamic),Vi ...

  10. sqlserver数据库的启动

    sqlserver实例几种启动的方法: (1)在WINDOWS服务控制台里手动启动,或者自动启动(默认) 第二种方式是SQLSERVER本身自已提供的启动方式,可以手动启动 (3)在SQLSERVER ...