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下的。

具体代码实现:

@Component
public 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 。

具体代码实现:

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

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

(点击文字可跳转)

1. 深究Spring中Bean的生命周期

2. 深入SpringBoot核心注解原理

3.线上环境部署概览

4.Springboot Vue shiro 实现前后端分离、权限控制

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. P3398 仓鼠找sugar(树链剖分)

    P3398 仓鼠找sugar 题目描述 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴是一个树形结构.这一天小仓鼠打算从从他的卧室(a)到餐厅(b),而 ...

  2. c++实验4

    1. 车辆基本信息管理  #include <iostream> using namespace std; #include <string> #include "c ...

  3. leetcode 【 Merge Sorted Array 】python 实现

    题目: Given two sorted integer arrays A and B, merge B into A as one sorted array. Note:You may assume ...

  4. IOS笔记048-数据存储

      IOS数据存储的几种方式         XML属性列表(plist)         归档 Preference(偏好设置)          NSKeyedArchiver归档(NSCodin ...

  5. IOS开发学习笔记012-核心语法

    1.点语法 2.成员变量的作用域 3. @property和@synthesize 4.id类型 5.构造方法 6.自定义构造方法 7.模板修改 8.Category - 分类 9.类扩展 一.点语法 ...

  6. 《HTTP协议详解》读书笔记---请求篇之消息报头

    不管是请求消息还是响应消息都包含消息报头,那么消息报头包含哪些内容?他们都代表什么含义呢?以下将带着 这些问题去学习消息报头. http消息(不管是请求消息还是响应消息)都是由开始行,消息报头(可选) ...

  7. c++树及树与二叉树的转换

    此算法中的树结构为“左儿子有兄弟链接结构” 在这样的一个二叉树中,一个节点的左分支是他的大儿子节点,右分支为他的大兄弟节点. 这里讲的树有递归前根,中根,后根遍历,插入节点,插入兄弟节点,查找结点,释 ...

  8. Linux下librtmp使用及编程实战

    最近想做rtmp的推流.直播的小项目,不想直接使用FFmpeg进行推流,FFmpeg进行推流特别简单,因为它已经将编码以及librtmp都集成好了,没啥意思.FFmpeg推流的例子,在雷神的博客里可以 ...

  9. ibatis selectKey

    <insert id="insert" parameterClass="A"> <selectKey keyProperty="uu ...

  10. 【转】Unity3D学习日记(二)使用UGUI制作虚拟摇杆控制摄像机

    http://blog.csdn.net/begonia__z/article/details/51178907 前天撸了一个简单的UGUI虚拟摇杆,今天我就利用前天做的虚拟摇杆做了一个简单的摄像机控 ...