一,什么是CORS?

1,CORS(跨域资源共享)(CORS,Cross-origin resource sharing),
它是一个 W3C 标准中浏览器技术的规范,
它允许浏览器向非同一个域的服务器发送XMLHttpRequest请求,
避免了Ajax只能在同一个域的服务器下使用的限制
 
2,什么是跨域问题?
跨域问题指的是浏览器不能执行其他网站的脚本.
它是由浏览器的同源策略造成的,因为浏览器对javascript施加有安全限制.
当前所有的浏览器都实行同源策略,所谓的同源指的是
  • 协议相同
  • 域名相同
  • 端口相同
浏览器执行javascript脚本时,会检查这个脚本属于哪个页面,
如果不是同源页面,就不会被执行.
说明:如果是指向相同ip的域名,也会被认为是跨域,例如:
127.0.0.1 和 localhost,也会被浏览器认为发生了跨域
 
3,允许跨域时浏览器的返回信息:
   

可以看到其中的:Access-Control-Allow-Origin: http://127.0.0.1:1999

   禁止跨域时浏览器的返回信息:
  

4,在生产环境中要注意的地方:

互联网搜索到的很多例子直接允许所有的域访问所有的路径,

这是绝对不能做的,

因为在互联网上被这样访问会引发安全问题

    必须指定明确的路径和明确的域
 

说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.com/architectforest

对应的源码可以访问这里获取: https://github.com/liuhongdi/

说明:作者:刘宏缔 邮箱: 371125307@qq.com

 

二,演示项目的说明

1,项目地址:
https://github.com/liuhongdi/corsconfig
2,项目功能说明:
   演示了两种解决cors问题的方法:
   WebMvcConfigurer配置
   @CrossOrigin注解
 
3,项目结构;如图:

三,java代码说明

1,CorsConfig.java

@Configuration
public class CorsConfig implements WebMvcConfigurer {
//指定允许跨域的多个域
private static final String[] ALLOWED_ORIGINS = {"http://www.baidu.com","http://127.0.0.1:81","https://blog.csdn.net"};
@Bean
public WebMvcConfigurer corsConfigurer() {
//添加跨域的cors配置
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/goods/**"). //可以被跨域的路径,/**表示无限制,
allowedOrigins(ALLOWED_ORIGINS). //允许跨域的域名,如果值为*,则表示允许任何域名使用
allowedMethods("*"). //允许任何方法,值可以为: "GET", "POST" ...
allowedHeaders("*"). //允许任何请求头
allowCredentials(true). //允许带cookie信息
exposedHeaders(HttpHeaders.SET_COOKIE).maxAge(3600L); //maxAge(3600):表示3600秒内,不需要再发送预检验请求,是结果可以缓存的时长
}
};
}
}

说明:用addCorsMapping方法添加对跨域路径/允许跨域的域名等的规则

2,HomeController.java

@RestController
@RequestMapping("/home")
public class HomeController {
//允许跨域多个值
@CrossOrigin(origins = {"http://127.0.0.1:1999","http://cas.baidu.com","http://do.baidu.com"},maxAge = 3600)
@GetMapping
@RequestMapping("/home")
public String home() {
return "this is /home/home";
} //允许跨域,只有一个域
//只写@CrossOrigin 表示允许所有域访问
@CrossOrigin("http://127.0.0.1:1999")
@GetMapping
@RequestMapping("/index")
public String index() {
return "this is /home/index";
}
}

演示用@CrossOrigin注解为指定的方法或类来指定跨域的规则

3,GoodsController.java

@RestController
@RequestMapping("/goods")
public class GoodsController {
@GetMapping
@RequestMapping("/one")
public String one() {
return "this is /goods/one";
}
}

供测试用,CorsConfig.java中配置了它的跨域规则

 

四, javascript代码说明

1,page81.html
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title >标题</title>
<meta charset="utf-8" />
<script type="text/javascript" language="JavaScript" src="/jquery-1.6.2.min.js"></script>
</head>
<body>
<div id="content" style="width:800px;">
<div style="width:250px;float:left;font-size: 16px;" ></div>
<div style="width:550px;float:left;">
<!--====================main begin=====================-->
<a href="javascript:get_home()" >访问8080:/home/home</a><br/>
<a href="javascript:get_goods()" >访问8080:/goods/one</a>
<!--====================main end=====================-->
</div>
</div> <script>
//访问8080:/goods/one
function get_goods(){
$.ajax({
type:"GET",
url:"http://127.0.0.1:8080/goods/one",
//返回数据的格式
datatype: "text",//"xml", "html", "script", "json", "jsonp", "text".
processData: false,
contentType: false,
//成功返回之后调用的函数
success:function(data){
alert(data);
},
//调用执行后调用的函数
complete: function(XMLHttpRequest, textStatus){
},
//调用出错执行的函数
error:function(jqXHR,textStatus,errorThrown){
console.log(jqXHR);
console.log(textStatus);
console.log(errorThrown);
}
});
} //访问8080:/home/home
function get_home(){
$.ajax({
type:"GET",
url:"http://127.0.0.1:8080/home/home",
//返回数据的格式
datatype: "text",//"xml", "html", "script", "json", "jsonp", "text".
processData: false,
contentType: false,
//成功返回之后调用的函数
success:function(data){
alert(data);
},
//调用执行后调用的函数
complete: function(XMLHttpRequest, textStatus){
},
//调用出错执行的函数
error:function(jqXHR,textStatus,errorThrown){
console.log(jqXHR);
console.log(textStatus);
console.log(errorThrown);
}
});
}
</script>
</body>
</html>

说明:把这个页面放到本地端口为81的域下

2,page1999.html

<html xmlns="http://www.w3.org/1999/xhtml">
<head >
<title >标题</title>
<meta charset="utf-8" />
<script type="text/javascript" language="JavaScript" src="/jquery-1.6.2.min.js"></script>
</head>
<body>
<div id="content" style="width:800px;">
<div style="width:250px;float:left;font-size: 16px;" ></div>
<div style="width:550px;float:left;">
<!--====================main begin=====================-->
<a href="javascript:get_index()" >访问8080:/home/index</a><br/>
<a href="javascript:get_home()" >访问8080:/home/home</a><br/>
<a href="javascript:get_goods()" >访问8080:/goods/one</a>
<!--====================main end=====================-->
</div>
</div>
<script>
//访问8080:/goods/one
function get_goods(){
$.ajax({
type:"GET",
url:"http://127.0.0.1:8080/goods/one",
//返回数据的格式
datatype: "text",//"xml", "html", "script", "json", "jsonp", "text".
processData: false,
contentType: false,
//成功返回之后调用的函数
success:function(data){
alert(data);
},
//调用执行后调用的函数
complete: function(XMLHttpRequest, textStatus){
},
//调用出错执行的函数
error:function(jqXHR,textStatus,errorThrown){
console.log(jqXHR);
console.log(textStatus);
console.log(errorThrown);
}
});
}
//访问8080:/home/index
function get_index(){
$.ajax({
type:"GET",
url:"http://127.0.0.1:8080/home/index",
//返回数据的格式
datatype: "text",//"xml", "html", "script", "json", "jsonp", "text".
processData: false,
contentType: false,
//成功返回之后调用的函数
success:function(data){
alert(data);
},
//调用执行后调用的函数
complete: function(XMLHttpRequest, textStatus){
},
//调用出错执行的函数
error:function(jqXHR,textStatus,errorThrown){
console.log(jqXHR);
console.log(textStatus);
console.log(errorThrown);
}
});
}
//访问8080:/home/home
function get_home(){
$.ajax({
type:"GET",
url:"http://127.0.0.1:8080/home/home",
//返回数据的格式
datatype: "text",//"xml", "html", "script", "json", "jsonp", "text".
processData: false,
contentType: false,
//成功返回之后调用的函数
success:function(data){
alert(data);
},
//调用执行后调用的函数
complete: function(XMLHttpRequest, textStatus){
},
//调用出错执行的函数
error:function(jqXHR,textStatus,errorThrown){
console.log(jqXHR);
console.log(textStatus);
console.log(errorThrown);
}
});
}
</script>
</body>
</html>

说明:把这个页面放到本地端口为1999的域下

 

五,效果测试

1,访问:
http://127.0.0.1:1999/page1999.html

效果:

测试可以发现:

/home/index,/home/home允许访问,

而/goods/one不允许访问,因为没有允许从127.0.0.1:1999访问到8080的java项目的规则

2,访问:

http://127.0.0.1:81/page81.html

效果:

可以测试发现:

访问到 /goods/one没有问题,

访问到/home/home会报错,

因为没有允许从127.0.0.1:81访问到8080的java项目的规则

 

六,查看spring boot版本

  .   ____          _            __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.3.2.RELEASE)

spring boot:解决cors跨域问题的两种方法(spring boot 2.3.2)的更多相关文章

  1. 解决ajax跨域问题的一种方法

    解决ajax跨域问题的一种方法 前后端分离经常用json来传输数据,比较常见的问题就有ajax跨域请求的错误问题,这里是我的一种解决方法: 在java中加入如下的注解类: import org.spr ...

  2. Ajax实现跨域访问的两种方法

    调程序时遇到"已拦截跨源请求:同源策略禁止读取位于--的远程资源",这是因为通过ajax调用其他域的接口会有跨域问题. 解决方法如下: 方法一:服务器端(PHP)设置header头 ...

  3. ASP.NET MVC 实现AJAX跨域请求的两种方法

    通常发送AJAX请求都是在本域内完成的,也就是向本域内的某个URL发送请求,完成部分页面的刷新.但有的时候需要向其它域发送AJAX请求,完成数据的加载,例如Google. 在ASP.NET MVC 框 ...

  4. PHP允许AJAX跨域请求的两种方法

    * 一. 服务端设置 header 头允许AJAX跨域 ** 代码如下: // 允许 ityangs.net 发起的跨域请求 header("Access-Control-Allow-Ori ...

  5. System.Web.Http.Cors配置跨域访问的两种方式

    System.Web.Http.Cors配置跨域访问的两种方式 使用System.Web.Http.Cors配置跨域访问,众多大神已经发布了很多文章,我就不在详细描述了,作为小白我只说一下自己的使用心 ...

  6. SpringBoot解决cors跨域问题

    1.使用@CrossOrigin注解实现 (1).对单个接口配置CORS @CrossOrigin(origins = {"*"}) @PostMapping("/hel ...

  7. spring 配置文件 引入外部的property文件的两种方法

    spring  的配置文件 引入外部的property文件的两种方法 <!-- 引入jdbc配置文件    方法一 --> <bean id="propertyConfig ...

  8. spring security实现动态配置url权限的两种方法

    缘起 标准的RABC, 权限需要支持动态配置,spring security默认是在代码里约定好权限,真实的业务场景通常需要可以支持动态配置角色访问权限,即在运行时去配置url对应的访问角色. 基于s ...

  9. Spring MVC学习总结(10)——Spring MVC使用Cors跨域

    跨站 HTTP 请求(Cross-site HTTP request)是指发起请求的资源所在域不同于该请求所指向资源所在的域的 HTTP 请求.比如说,域名A(http://domaina.examp ...

随机推荐

  1. [剑指Offer]17-打印从1到最大的n位数(递归)

    题目 如题,输入n,则从1打印至99. 题解 考虑到n比较大会有大数问题,所以使用字符数组存储数. 由题可用递归求n位全排列,即为所得. 具体地,用临时字符数组用来存答案,每次递归填好一位,都填好后输 ...

  2. [HDU2577]How to Type(DP)

    题目链接 题意 给一个大小写字符串,求最少敲击字符串次数,最开始和最后要求shift都是down的.如日常,大小写转换可以ctrl+z或者shift保持 up/down. 题解 两个dp数组,一个表示 ...

  3. grpc服务如何添加sentry监控(添加中间件)

    目录 需求 解决 需求 sentry是一款非常好用的工具,可以方便追踪线上的异常,在gin框架里边可以非常方便的使用Use添加中件间,grpc服务在网上搜索了一堆没一个能用的,只能硬着头皮看源码 终于 ...

  4. java Spring系列之 配置文件的操作 +Bean的生命周期+不同数据类型的注入简析+注入的原理详解+配置文件中不同标签体的使用方式

    Spring系列之 配置文件的操作 写在文章前面: 本文带大家掌握Spring配置文件的基础操作以及带领大家理清依赖注入的概念,本文涉及内容广泛,如果各位读者耐心看完,应该会对自身有一个提升 Spri ...

  5. Codeforces1131G Most Dangerous Shark

    Description Original Problem Chinese Translation 大概就是给你一个间隔为1的多米诺序列,推倒一个多米诺骨牌有个花费,求推倒所有多米诺骨牌的最小花费 So ...

  6. Spring学习(十)Spring知识点汇总

    一.基础概念 Q:Spring是什么? 定义:Spring是一个轻量级的IoC(控制反转)和AOP容器框架. 目的:用于简化企业应用程序的开发,使得开发者只需要关心业务需求. 常见的配置方式: 基于X ...

  7. Spring学习(八)AOP详解

    文章更新时间:2020/04/06 一.一个例子 在上面的例子中,包租婆的核心业务就是签合同,收房租,那么这就够了,灰色框起来的部分都是重复且边缘的事,交给中介商就好了,这就是 AOP 的一个思想:让 ...

  8. C++获取运行程序当前目录

    1 HMODULE GetSelfModuleHandle() 2 { 3 MEMORY_BASIC_INFORMATION mbi; 4 return ((::VirtualQuery(GetSel ...

  9. Hadoop框架:HDFS简介与Shell管理命令

    本文源码:GitHub·点这里 || GitEE·点这里 一.HDFS基本概述 1.HDFS描述 大数据领域一直面对的两大核心模块:数据存储,数据计算,HDFS作为最重要的大数据存储技术,具有高度的容 ...

  10. 什么是64位和32位internet explorer

    什么是64位和32位internet explorer 如果您使用 64 位版本的 Internet Explorer 时,您会遇到问题,请尝试使用 32 位版本的 Internet Explorer ...