千家信息网

Springboot如何解决ajax自定义headers的跨域请求问题

发表于:2024-11-19 作者:千家信息网编辑
千家信息网最后更新 2024年11月19日,本篇内容主要讲解"Springboot如何解决ajax自定义headers的跨域请求问题",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Springboot
千家信息网最后更新 2024年11月19日Springboot如何解决ajax自定义headers的跨域请求问题

本篇内容主要讲解"Springboot如何解决ajax自定义headers的跨域请求问题",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Springboot如何解决ajax自定义headers的跨域请求问题"吧!

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方法

@Configuration public class CorsConfig {   private CorsConfiguration buildConfig() {     CorsConfiguration corsConfiguration = new CorsConfiguration();     corsConfiguration.addAllowedOrigin("*"); // 1允许任何域名使用    corsConfiguration.addAllowedHeader("*"); // 2允许任何头    corsConfiguration.addAllowedMethod("*"); // 3允许任何方法(post、get等)     return corsConfiguration;   }   @Bean   public CorsFilter corsFilter() {     UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();     source.registerCorsConfiguration("/**", buildConfig()); // 4     return new CorsFilter(source);   } }

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

$.ajax({    type:"GET",    url:"http://localhost:8766/main/currency/sginInState",    dataType:"JSON",    data:{      uid:userId    },    beforeSend: function (XMLHttpRequest) {      XMLHttpRequest.setRequestHeader("Authorization", access_token);    },    success:function(res){      console.log(res.code)    }  })

此时请求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中添加

spring:
mvc:
dispatch-options-request: true

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

②添加过滤器配置

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

具体代码实现:

@Componentpublic class RequestFilter implements HandlerInterceptor {  public boolean preHandler(HttpServletRequest request,HttpServletResponse response,Object handler){    response.setHeader("Access-Control-Allow-Origin", "*");    response.setHeader("Access-Control-Allow-Credentials", "true");    response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS");    response.setHeader("Access-Control-Max-Age", "86400");    response.setHeader("Access-Control-Allow-Headers", "Authorization");    // 如果是OPTIONS请求则结束    if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) {      response.setStatus(HttpStatus.NO_CONTENT.value());      return false;    }    return true;  }}

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

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

具体代码实现:

@Componentpublic class MyWebConfiguration extends WebMvcConfigurationSupport{  @Resource  private RequestFilter requestFilter;  @Override  public void addInterceptors(InterceptorRegistry registry) {    // 跨域拦截器    registry.addInterceptor(requestFilter).addPathPatterns("/**");  }}

到此,相信大家对"Springboot如何解决ajax自定义headers的跨域请求问题"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

0