SpringMVC CORS跨域解决方案 2021-9-20

news/2024/7/11 1:05:26 标签: ajax, jquery, java

SpringMVC 应用开发

1 基础概念介绍
2 返回值处理
3 参数绑定处理
4 RequestMapping注解
5 RESTful支持
6 拦截器应用
7 CORS跨域解决方案
8 Mock测试(模拟测试)
9 ControllerAdvice
10 乱码解决
11 非注解开发方式


CORS跨域解决方案

  • SpringMVC 应用开发
  • 一、 什么是跨域
  • 二、 如何解决跨域
  • 三、 使用CORS跨域
    • 3.1 什么是CORS
    • 3.2 客户端跨域处理 (了解)
      • 3.2.1 对于简单请求
      • 3.2.2 非简单请求
        • 请求信息
    • 3.3 服务器端跨域处理
      • 3.3.1 springmvc4.x 以下,使用 springmvc 的拦截器实现
        • 跨域不提交Cookie
        • 跨域提交Cookie
      • 3.3.2 SpringMVC4.x 以上处理 CORS 跨域方式

一、 什么是跨域

浏览器因为安全考虑,所以设置了同源策略。同源策略简单理解就是DNS域名,端口号,协议完全相同
就称为同源。同源下的页面之间才能进行js的dom操作,如果不在同一个源下任何跨文档dom访问都是
被阻止的。不同源下的访问可以称之为跨域访问。

1、端口号不同 http://www.baidu.com/a.js vs. http://www.baidu.com:8080/b.js
2、主域相同子域不同 http://www.baidu.com/a.js vs. http://blog.baidu.com/b.js
3、协议不同 http://www.baidu.com/a.js vs. https://www.baidu.com/b.js
4、域名不同 http://www.baidu.com/a.js vs. http://www.qq.com/b.js
5、域名和对应ip http://www.baidu.com/a.js vs. http://192.168.2.2/b.js
当然在实际应用中,多数出现在ajax请求时,在不同域下请求数据会遇到禁止跨域的问题。

二、 如何解决跨域

1、解决跨域主要考虑两方面:

  • 一个是避开 Ajax 请求方式;
  • 一个是解决同源限制的问题。

2、解决跨域的方式有多种:

  • 基于 JavaScript标签 的 src 方式
  • 基于 Jquery 的 JSONP 方式
  • 基于 CORS 的方式(解决同源的问题)

JSONP 和 CORS 的区别:
JSONP 只能解决 GET 方式提交
CORS 不仅支持 GET 方式,同时也支持 POST 提交方式。

三、 使用CORS跨域

3.1 什么是CORS

CORS 是一个 W3C 标准,全称是"跨域资源共享"( Cross-origin resource sharing )。
它允许浏览器向跨源服务器,发出 XMLHttpRequest 请求,从而克服了 AJAX 只能同源使用的限
制。
CORS 需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能, IE 浏览器不能低于
IE10 。

  • CORS 原理:
    1、客户端自动向请求头 header 中注入 Origin 。
    2、服务器端需要向响应头 header 中注入 Access-Control-Allow-Origin
    3、浏览器检测到 header 中的 Access-Control-Allow-Origin ,则就可以跨域操作了。

3.2 客户端跨域处理 (了解)

请求分类标准
浏览器将 CORS 请求分成两类:简单请求( simple request )和非简单请求( not-so-simple request )。

1、 请求方法是以下三种方法之一:HEAD GET POST
2、HTTP的头信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

3.2.1 对于简单请求

浏览器直接发出 CORS 请求。具体来说,就是在头信息之中,增加一个 Origin 字段。
(1)Access-Control-Allow-Origin 该字段是必须的。它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。
(2)Access-Control-Allow-Credentials 该字段可选。它的值是一个布尔值,表示是否允许发送Cookie。 默认情况下,Cookie不包括在CORS请求之中。如果 设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。 这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。

3.2.2 非简单请求

非简单请求是那种对服务器有特殊要求的请求,比如请求方法是 PUT 或 DELETE ,或者 Content-Type
字段的类型是 application/json 。
非简单请求的 CORS 请求,会在正式通信之前,增加一次 HTTP 查询请求,称为"预检"请求
( preflight )。

请求信息

1、 HTTP 请求的方法是 PUT ,并且发送一个自定义头信息 X-Custom-Header 。
浏览器发现,这是一个非简单请求,就自动发出一个"预检"请求,要求服务器确认可以这样请求。下面
是这个"预检"请求的 HTTP 头信息。

2、"预检"请求用的请求方法是 OPTIONS ,表示这个请求是用来询问的。头信息里面,关键字段是
Origin ,表示请求来自哪个源。
除了 Origin 字段,"预检"请求的头信息包括两个特殊字段。
(1)Access-Control-Request-Method 该字段是必须的,用来列出浏览器的CORS请求会用到哪些HTTP方法,上例是PUT。
(2)Access-Control-Request-Headers 该字段是一个逗号分隔的字符串,指定浏览器CORS请求会额外发送的头信息字段,上例是X-Custom- Header。

3、一旦服务器通过了"预检"请求,以后每次浏览器正常的 CORS 请求,就都跟简单请求一样,会有一个Origin 头信息字段。服务器的回应,也都会有一个 Access-Control-Allow-Origin 头信息字段。

3.3 服务器端跨域处理

3.3.1 springmvc4.x 以下,使用 springmvc 的拦截器实现

cookie 一般也需要跨域提交cookie。

跨域不提交Cookie

java">public class AllowOriginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {
        // 有跨域行为时参考网址 http://namezhou.iteye.com/blog/2384434
        if (request.getHeader("Origin") != null) {
            response.setContentType("text/html;charset=UTF-8");
            // 允许哪一个URL
            response.setHeader("Access-Control-Allow-Origin", "*");
            // 允许那种请求方法
            response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
             response.setHeader("XDomainRequestAllowed", "1");
             System.out.println("正在跨域");
        }
        return true;
        }
    }

跨域提交Cookie

注意事项

  • Access-Control-Allow-Credentials 为 true 的时候, Access-Control-Allow-Origin 一定
    不能设置为”*”,否则报错。
  • 如果有多个拦截器,一定要把处理跨域请求的拦截器放到首位。
java">在这里插入代码片public class AllowOriginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {
        // 有跨域行为时参考网址 http://namezhou.iteye.com/blog/2384434 
        if (request.getHeader("Origin") != null) {
            response.setContentType("text/html;charset=UTF-8");
            // 允许哪一个URL 访问 request.getHeader("Origin") 根据请求来的url动态允许 
            response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
            // 允许那种请求方法 
            response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE,HEAD");
            response.setHeader("Access-Control-Max-Age", "0");
            // 允许请求头里的参数列表 
            response.setHeader("Access-Control-Allow-Headers", "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M- With,userId,token");
            // 允许对方带cookie访问 
            response.setHeader("Access-Control-Allow-Credentials", "true");
            response.setHeader("XDomainRequestAllowed", "1");
            System.out.println("正在跨域");
        }
        return true;
    }
}

前端代码:
JS代码

javascript">$.ajax({ 
	url: '自己要请求的url', 
	method:'请求方式', //GET POST PUT DELETE 
	xhrFields:{ 
		withCredentials:true 
	},
	success:function(data){ 
	//自定义请求成功做什么 
	},
	error:function(){ 
	//自定义请求失败做什么 
	}
})

3.3.2 SpringMVC4.x 以上处理 CORS 跨域方式

  • 某个方法可以跨域访问,在某个方法上使用 @CrossOrigin
  • 某个 Controller 类都可以跨域访问,在类上上使用 @CrossOrigin
  • 全局访问,在 springmvc.xml 中配置
<mvc:cors> 
	<mvc:mapping path="/**"/> 
</mvc:cors>

http://www.niftyadmin.cn/n/1857576.html

相关文章

Arcgis for Androd API开发系列教程(一)——地图显示与GPS定位

序&#xff1a;最近呢&#xff0c;工作鸭梨不是怎么大&#xff0c;对于自己爱折腾的想法又冒出了水面&#xff0c;开始自己的android开发的学习之旅。但是呢&#xff0c;本人是做GIS的&#xff0c;所以呢&#xff0c;就打算从这方面入手看看&#xff0c;是不是有什么比较好玩的…

机器人全面替换工人?别急,人机搭配才能干活不累

By 超神经场景描述&#xff1a;随着机械与自动化的技术发展&#xff0c;生产制造业一直在积极跟进和使用最先进的技术&#xff0c;来提高生产效率。大量工厂重金引进自动化生产装置&#xff0c;免不了产生技术故障导致的问题&#xff0c;如何平衡人类操作工和工业 AI&#xff0…

14-自定义错误函数-错误处理器

<?php//自定义错误函数function my_error($errno,$errmes){echo "错误编号&#xff1a;".$errno."<br/>";echo "错误信息是&#xff1a;".$errmes;exit();}//改写set_error_handler处理方法&#xff0c;回调函数set_error_handler(&qu…

Arcgis Add-In开发入门实例

作为一个本科侧重于应用&#xff0c;工作之后却做了开发的程序员来说&#xff0c;做GIS&#xff0c;开发应该是一门必修课&#xff0c;只是&#xff0c;苦于各种原因吧&#xff0c;做GIS应用的人会开发的很少&#xff0c;做GIS开发的大部分都是计算机出身&#xff0c;痛心疾首啊…

马斯克上电视:25 年内全脑界面,将实现人类与 AI 共生

埃隆马斯克昨日参加了播客节目《乔罗根秀》&#xff0c;接受了喜剧演员、播客主持人乔罗根的采访。这是马斯克第二次参加《乔罗根秀》&#xff0c;上一次是在 2018 年。伊隆马斯克的愿景是将人的大脑与计算机连接起来&#xff0c;以避免我们的物种被人工智能赶超。这个梦想将成…

MySQL定时器开启、调用实现代码

创建测试表 CREATE TABLE t ( v VARCHAR(100) NOT NULL ) ENGINE INNODB DEFAULT CHARSETutf8; 创建定时器 调用的存储过程 DELIMITER $$ DROP PROCEDURE IF EXISTS e_test $$ CREATE PROCEDURE e_test() BEGIN INSERT INTO t VALUES(1); END $$ DELIMITER ; 要使…

Mybatis入门与编码流程 2021-09-20

Mybatis 应用 1 Mybatis 入门与编码流程 2 mapper代理开发方式 3 全局配置文件 4 输入映射和输出映射 5 关联查询 6 延迟加载 7 动态SQL 8 Mybatis缓存 Mybatis 入门与编码流程Mybatis 应用一、 Mybatis是什么1.1 Mybatis的由来1.2 ORM是什么1.3 ORM框架和MyBatis的区别二、编…

GIS的核心价值——服务

注&#xff1a;本观点仅代表个人观点&#xff0c;与任何人员或者组织无任何关系&#xff0c;如有雷同或者相似之处&#xff0c;只能说明我们对GIS的理解相同&#xff0c;无抄袭之嫌。 写这个题目&#xff0c;源于前两天接到的一个电话面试时候问道的一个面试题。当时&…