Spring Boot 通过CORS实现跨域问题

同源策略

很多人对跨域有一种误解,以为这是前端的事,和后端没关系,其实不是这样的,说到跨域,就不得不说说浏览器的同源策略。

同源策略是由 Netscape 提出的一个著名的安全策略,它是浏览器最核心也最基本的安全功能,现在所有支持 JavaScript 的浏览器都会使用这个策略。所谓同源是指协议、域名以及端口要相同。同源策略是基于安全方面的考虑提出来的,这个策略本身没问题,但是我们在实际开发中,由于各种原因又经常有跨域的需求,传统的跨域方案是 JSONP,JSONP 虽然能解决跨域但是有一个很大的局限性,那就是只支持 GET 请求,不支持其他类型的请求,而今天我们说的 CORS(跨域源资源共享)(CORS,Cross-origin resource sharing)是一个 W3C 标准,它是一份浏览器技术的规范,提供了 Web 服务从不同网域传来沙盒脚本的方法,以避开浏览器的同源策略,这是 JSONP 模式的现代版。

实践

首先,我们新建两个工程:

新建工程一:cors1 project

勾选Web模块 因为我们等下需要通过web接口进行测试 点击Finish完成构建

在cors1 中 我们新建一个HelloController,写上一个测试接口:

@RestController
public class HelloController {

  @GetMapping("/hello")
  public String hello(){
    return "hello cors1";
  }
}

新建工程二:cors2 project

对应的勾选Web模块进行构建。

在cors2的static目录下,建立Index.html,并编写一个GET请求按钮,发起Ajax请求(前提:static目录下有jquery.js)
请求cors1 工程的 localhost:8080/hello接口

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="jquery3.3.1.js"></script>
</head>
<body>
<div id="app"></div>
<input type="button" value="GET" onclick="getData()">
<input type="button" value="PUT" onclick="putData()">
<script>
  function getData() {
    $.get("http://localhost:8080/hello",function (msg) {
      $("#app").html(msg);
    })
  }
</script>
</body>
</html>

并设定cors2 工程的项目端口:

server.port = 8081

分别启动cors1 和 cors2

访问 localhost:8081/index.html 点击按钮,发送请求:

访问报错,目前不支持跨域,验证了上面说的 同源策略

解决方案一:

1.在Controller类 或 接口方法上,使用 注解 @CrossOrigin 指定允许哪个域服务器访问

@RestController
public class HelloController {

  @GetMapping("/hello")
  @CrossOrigin(origins = "http://localhost:8081")
  public String hello(){
    return "hello cors1";
  }
}

重启 Cors1 项目,点击发送请求:

访问成功,浏览器控制台也没有报错

注意:
这种方式有一个弊端,就是我们需要在对外开放的每个接口或者类上都要写一遍,大大增加了开发的重复性和繁琐性

解决方案二

Spring Boot 中,可以通过全局配置一次性解决这个问题,全局配置只需要在 SpringMVC 的配置类中重写 **addCorsMappings **方法即可

package org.taoguoguo;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @author taoguoguo
 * @description WebMvcConfig
 * @website https://www.cnblogs.com/doondo
 * @create 2020-09-01 21:31
 */
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

  /**
   * 跨域全局配置
   * @param registry
   */
  @Override
  public void addCorsMappings(CorsRegistry registry) {
    //addMapping 允许哪些接口跨域
    //allowedOrigins 允许哪个域服务器访问
    //allowedHeaders 允许通过的请求头
    //maxAge 服务器在发送一些请求(例如put)会先发一个探测请求,避免每次都需要发送探测请求 可以设置有效期
    registry.addMapping("/**")
        .allowedOrigins("http://localhost:8081")
        .allowedHeaders("*")
        .allowedMethods("*")
        .maxAge(30*1000);
  }
}

/** 表示本应用的所有方法都会去处理跨域请求,allowedMethods 表示允许通过的请求数,allowedHeaders 则表示允许的请求头。经过这样的配置之后,就不必在每个方法上单独配置跨域了

现在再去页面访问,也是没有问题的

探测请求

我们在跨域设置中

maxAge 服务器在发送一些请求(例如put)会先发一个探测请求,避免每次都需要发送探测请求 可以设置有效

先举一个例子:
我们在Cors1中添加一个put请求

@RestController
public class HelloController {

  @GetMapping("/hello")
  @CrossOrigin(origins = "http://localhost:8081")
  public String hello(){
    return "hello cors1";
  }

  @PutMapping("/doput")
  public String doput(){
    return "doput";
  }
}

在cors2中增加put请求发送按钮

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="jquery3.3.1.js"></script>
</head>
<body>
<div id="app"></div>
<input type="button" value="GET" onclick="getData()">
<input type="button" value="PUT" onclick="putData()">
<script>
  function getData() {
    $.get("http://localhost:8080/hello",function (msg) {
      $("#app").html(msg);
    })
  }

  function putData() {
    $.ajax({
      type:'put',
      url: 'http://localhost:8080/doput',
      success:function (msg) {
        $("#app").html(msg);
      }
    })

  }
</script>
</body>
</html>

启动cors1 cors2 发送put请求:

我们看到请求一次 浏览器会发送两次请求,其中Request Methods 为 options 的即为探测请求
因为我们设置了探测请求的有效期,因此当我们再次发送时,浏览器只会发送一次请求

了解了整个 CORS 的工作过程之后,我们通过 Ajax 发送跨域请求,虽然用户体验提高了,但是也有潜在的威胁存在,常见的就是 CSRF(Cross-site request forgery)跨站请求伪造。跨站请求伪造也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF,是一种挟制用户在当前已登录的 Web 应用程序上执行非本意的操作的攻击方法

假如一家银行用以运行转账操作的URL地址如下:**http://icbc.com/aa?bb=cc**,那么,一个恶意攻击者可以在另一个网站上放置如下代码:**<img src="http://icbc.com/aa?bb=cc">**,如果用户访问了恶意站点,而她之前刚访问过银行不久,登录信息尚未过期,那么她就会遭受损失。

基于此,浏览器在实际操作中,会对请求进行分类,分为简单请求,预先请求,带凭证的请求等,预先请求会首先发送一个 options 探测请求,和浏览器进行协商是否接受请求。默认情况下跨域请求是不需要凭证的,但是服务端可以配置要求客户端提供凭证,这样就可以有效避免 csrf 攻击。

总结

到此这篇关于Spring Boot 通过CORS实现跨域问题的文章就介绍到这了,更多相关Spring Boot实现跨域内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • vue+springboot实现项目的CORS跨域请求

    跨域资源共享CORS(Cross-origin Resource Sharing),是W3C的一个标准,允许浏览器向跨源的服务器发起XMLHttpRequest请求,克服ajax请求只能同源使用的限制.关于CORS的详细解读,可参考阮一峰大神的博客:跨域资源共享CORS详解.本文为通过一个小demo对该博客中分析内容的一些验证. 1.springboot+vue项目的构建和启动 细节不在此赘述,任何简单的springboot项目就可以,而前端vue项目只需用axios发ajax请求即可. 我的d

  • Spring Boot Web应用开发 CORS 跨域请求支持

    一.Web开发经常会遇到跨域问题,解决方案有:jsonp,iframe,CORS等等 CORS与JSONP相比 1. JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求. 2. 使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理. 3. JSONP主要被老的浏览器支持,它们往往不支持CORS,而绝大多数现代浏览器都已经支持了CORS 浏览器支持情况 Chrome 3+ Firefox 3.5+ Opera 12+ Sa

  • 浅谈spring-boot 允许接口跨域并实现拦截(CORS)

    本文介绍了spring-boot 允许接口跨域并实现拦截(CORS),分享给大家,也给自己留个笔记 pom.xml(依赖的jar) // 在spring-boot-starter-web的启动器中,已经依赖好了 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependen

  • 详解springboot设置cors跨域请求的两种方式

    1.第一种: public class CorsFilter extends OncePerRequestFilter { static final String ORIGIN = "Origin"; protected void doFilterInternal( HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOE

  • Spring boot 和Vue开发中CORS跨域问题解决

    跨域资源共享CORS(Cross-origin Resource Sharing),是W3C的一个标准,允许浏览器向跨源的服务器发起XMLHttpRequest请求,克服ajax请求只能同源使用的限制.关于CORS的详细解读,可参考阮一峰大神的博客:跨域资源共享CORS详解. 1. 遇到的问题: 我用spring-boot 做Rest服务,Vue做前端框架,用了element-admin-ui这个框架做后台管理.在调试的过程中遇到了如下错误: Preflight response is not

  • Spring Boot 通过CORS实现跨域问题

    同源策略 很多人对跨域有一种误解,以为这是前端的事,和后端没关系,其实不是这样的,说到跨域,就不得不说说浏览器的同源策略. 同源策略是由 Netscape 提出的一个著名的安全策略,它是浏览器最核心也最基本的安全功能,现在所有支持 JavaScript 的浏览器都会使用这个策略.所谓同源是指协议.域名以及端口要相同.同源策略是基于安全方面的考虑提出来的,这个策略本身没问题,但是我们在实际开发中,由于各种原因又经常有跨域的需求,传统的跨域方案是 JSONP,JSONP 虽然能解决跨域但是有一个很大

  • spring boot配合前端实现跨域请求访问

    一.方法: 服务端设置Respone Header头中Access-Control-Allow-Origin 配合前台使用jsonp 继承WebMvcConfigurerAdapter 添加配置类 二.实例: 1.前端:因为我们用了前后端分离,前端用node服务器,node服务器再用了ajax反向代理请求到我的spring boot 服务器.其中node服务器也用了ajax发出请求所以也存在跨域的问题.具体代码: app.all(apiRoot + '/*', proxy('127.0.0.1:

  • Spring Boot如何通过CORS处理跨域问题

    跨域的产生就是因为浏览器的同源策略.它是浏览器的核心安全功能,所谓的同源,就是指域名,协议,还有端口要相同.传统的方案就是JSONP(前端处理方案),但是JSONP有很大的局限性,就是只支持GET请求,所以不能满足我们的需求,而CORS(Cross-origin-resource sharing)跨域资源共享,就可以解决这个问题.他是一个浏览器规范,一个w3c标准,提供web服务从不同网域传来的沙盒脚本的方法,避开了浏览器的同源策略. CORS是后端的一种处理的方案,在Spring中可以配置解决

  • Javaweb使用cors完成跨域ajax数据交互

    跨域,指的是浏览器不能执行其他网站的脚本.它是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制. ajax本身实际上是通过XMLHttpRequest对象来进行数据的交互,而浏览器出于安全考虑,不允许js代码进行跨域操作,所以会警告. cors 全称:Cross-Origin Resource Sharing 中文意思:跨域资源共享 它在维基百科上的定义是:跨域资源共享(CORS )是一种网络浏览器的技术规范,它为Web服务器定义了一种方式,允许网页从不同的域访问其资源.而

  • JS跨域解决方案之使用CORS实现跨域

    引言 跨域是我在日常面试中经常会问到的问题,这词在前端界出现的频率不低,主要原因还是由于安全限制(同源策略, 即JavaScript或Cookie只能访问同域下的内容),因为我们在日常的项目开发时会不可避免的需要进行跨域操作,所以跨域能力也算是前端工程师的基本功之一. 和大多数跨域的解决方案一样,JSONP也是我的选择,可是某天PM的需求变了,某功能需要改成支持POST,因为传输的数据量比较大,GET形式搞不定.所以折腾了下闻名已久的CORS(跨域资源共享,Cross-Origin Resour

  • 浅析jsopn跨域请求原理及cors(跨域资源共享)的完美解决方法

    由于同源策略的缘故,ajax不能向不同域的网站发出请求. 比如a站localhost需要向b站请求数据,地址为:http://www.walk-sing.com/api.php 请求的代码如下: <html> <script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script> <script type="text/javascript"> $.get

  • django基于cors解决跨域请求问题详解

    一 同源策略 同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响.可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现 请求的url地址,必须与浏览器上的url地址处于同域上,也就是域名,端口,协议相同. 比如:我在本地上的域名是127.0.0.1:8000,请求另外一个域名:127.0.0.1:8001一段数据 浏览器上就会报错,这个就是同源策略的保护,如果浏览器对javas

  • Django通过设置CORS解决跨域问题

    一.Ajax 跨域请求 Ajax 请求一个目标地址为非本域(协议.主机.端口任意一个不同)的 web 资源. 前端 http://192.168.10.50:8080 后端 http://192.168.10.50:8000 Ajax 跨域请求保护的作用:防止跨站的攻击. 二.如何解决跨域的访问 当我们在现实当中有需要跨域访问资源,有两种解决方案: 前端解决:jsonp 后端解决(Django):CORS 专门解决方案 这篇文章主要介绍使用 Django 框架进行开发时的后端解决方案. 三.Dj

  • spring cloud如何修复zuul跨域配置异常的问题

    前言 本文主要给大家介绍一下在zuul进行跨域配置的时候出现异常该如何解决的方法,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 异常 The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed 实例 Access-Control-Allow-Credentials:true Access-Control-Allow-Credentials:t

  • Apache中配置支持CORS(跨域资源共享)实例

    当使用ajax跨域请求时,浏览器报错:XmlHttpRequest error: Origin null is not allowed by Access-Control-Allow-Origin.肯定是跨域的问题,如果用jsonp或者proxy的方式进行修改的话未免需要太大的工程量,所以采用CORS这种比较简单高效的技术.相比JOSP的方式,CORS更为高效.JSONP由于它的原理只能实现GET请求,而CORS支持所有类型的HTTP请求.使用CORS,可以使用普通的ajax实现跨域,这对于前端

随机推荐