Spring Boot 2.X优雅的解决跨域问题

一、什么是源和跨域

源(origin)就是协议、域名和端口号。

URL由协议、域名、端口和路径组成,如果两个URL的协议、域名和端口全部相同,则表示他们同源。否则,只要协议、域名、端口有任何一个不同,就是跨域。

对https://www.baidu.com/index.html进行跨域比较:

URL 是否跨域 原因
https://www.baidu.com/more/index.html 不跨域 三要素相同
https://map.baidu.com/ 跨域 域名不同
http://www.baidu.com/index.html 跨域 协议不同
https://www.baidu.com:81/index.html 跨域 端口号不同

随着前后端分离开发的越来越普及,会经常遇到跨域的问题,当我们在浏览器中看到这样的错误时,就需要意识到遇到了跨域:

二、什么是同源策略?

同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

同源策略又分为以下两种:

  • DOM同源策略:禁止对不同源页面DOM 进行操作。这里主要场景是iframe跨域的情况,不同域名的iframe是限制互相访问的。
  • XMLHttpRequest同源策略:禁止使用XHR对象向不同源的服务器地址发起HTTP请求。

三、Spring Boot跨域解决方案

本例使用Spring Boot 2.1.2.RELEASE演示,分别用8080和8081端口启动,部分代码如下:

跨域页面:testOtherDomain.html

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>不同域名-Java碎碎念</title>
</head>
<body>
<button id="b1">点我测试</button>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<script>
 $("#b1").click(function () {
  $.ajax({
   url: "http://localhost:8081/hello",
   type: "post",
   success:function (res) {
    console.log(res);
   }
  })
 });
</script>
</body>
</html>

接口类:HelloController

package com.example.helloSpringBoot.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
 @RequestMapping("/hello")
 public String HelloSpring (){
  return "hello Java碎碎念!";
 }
}

未解决跨域前运行截图:

在Spring Boot 2.X应用程序中可以使用注解@CrossOrigin,也可以通过使用WebMvcConfigurer对象来定义全局CORS配置。

1、@CrossOrigin注解示例代码

package com.example.helloSpringBoot.controller;

import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

 @CrossOrigin
 @RequestMapping("/hello")
 public String HelloSpring (){
  return "hello Java碎碎念!";
 }
}

2. WebMvcConfigurer对象示例代码

package com.example.helloSpringBoot.config;

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

@Configuration
public class MyConfiguration {
 @Bean
 public WebMvcConfigurer corsConfigurer() {
  return new WebMvcConfigurer() {
   @Override
   public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/*")
       .allowedOrigins("*")
       .allowCredentials(true)
       .allowedMethods("GET", "POST", "DELETE", "PUT","PATCH")
       .maxAge(3600);
   }
  };
 }
}

按照上面两种方式的一种配置完成后,即可实现对跨域的支持,运行成功截图如下:

完整源码地址:https://github.com/suisui2019/helloSpringBoot (本地下载)

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。

(0)

相关推荐

  • activemq整合springboot使用方法(个人微信小程序用)

    主题 ActiveMQ Spring Boot 小程序开发 1.引入依赖 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.3.RELEASE</version> <relativePath /> <!-- lookup

  • SpringBoot记录Http请求日志的方法

    在使用Spring Boot开发 web api 的时候希望把 request,request header ,response reponse header , uri, method 等等的信息记录到我们的日志中,方便我们排查问题,也能对系统的数据做一些统计. Spring 使用了 DispatcherServlet 来拦截并分发请求,我们只要自己实现一个 DispatcherServlet 并在其中对请求和响应做处理打印到日志中即可. 我们实现一个自己的分发 Servlet ,它继承于 D

  • Spring自带的校验框架Validation的使用实例

    1.首先来一个项目结构图以及所需jar包 可以看到,没有添加除了日志和jstl相关的jar包外,没有其他spring以外的第三方jar包(即使用的是spring自带的校验框架). 2.从前台页面开始,首先是接收用户信息的表单loginForm.jsp <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@

  • 详解Spring框架下向异步线程传递HttpServletRequest参数的坑

    在spring的注解 @RequestMapping 之下可以直接获取 HttpServletRequest 来获得诸如request header等重要的请求信息: @Slf4j @RestController @RequestMapping("/test") public class TestController { private static final String HEADER = "app-version"; @RequestMapping(value

  • spring boot定时任务接收邮件并且存储附件的方法讲解

    在spring boot中写定时任务很简单,两个注解就可以实现.在启动类中加@EnableScheduling ,然后在你需要定时的方法上加上@Scheduled(cron="0 10 8 * * ?"):括号内为cron表达式.如下图: 接收邮件及其判断是否有附件,并且存储附件. public class TimerTaskServiceImpl implements TimerTaskService { @Autowired private ParseTxtServiceImpl

  • 使用Docker部署Spring Boot的方法示例

    这里主要用到spring-boot开箱即用,能生成一个独立运行的程序,及maven的插件docker-maven-plugin 这里主要步骤 构建一个简单的springboot项目 添加docker-maven-plugin及写dockerfile 实践生成 docker镜像 一个简单 Spring Boot 项目 以spring boot 2.0 为例 在pom.xml文件中增加parament依赖 <parent> <groupId>org.springframework.bo

  • 使用dockercompose搭建springboot-mysql-nginx应用

    上篇使用docker构建spring-boot应用,是把编译好的jar包构建到镜像中. 这篇是把spring-boot连同数据库,做为一组docker服务运行起来. 这里只是把自己操作记录下来,完整运行的代码见"参考"中的引用1中的内容. (我修改mysql映射目录及获取远程ip的方法) 主要步骤: 搭建简单的springboot应用 应用添加docker下支持 编写dockercompose配置文件 实践运行 搭建简单的springboot应用 做一个web应用,统计访问该站点的ip

  • Springboot项目打war包docker包找不到resource下静态资源的解决方案

    前一段时间遇到一个问题,是关于读取项目中文件资源的问题.我是一个maven工程 我把一张照片放到resource下面,然后在本地读取的时候可以读取到,但是一旦打成WAR包以后就总是包找不到文件资源错误.我的war包是springboot打的war包,是内嵌的tomcat所以不解压,然后系统去找路径的时候会发现是个WAR包,而图片在WAR包内,所以找不到. 为了解决这个问题,我走了好多弯路,一直在路径上花费时间. 一开始使用修改配置文件的方式: # 配置静态资源访问前缀 spring.mvc.st

  • SpringCloud分布式链路跟踪的方法

    注:作者使用IDEA + Gradle 注:需要有一定的java SpringBoot and SSM+Springcloud基础 程序测试错误追责 我举个例子,我现在要做一个电商项目,项目里面有一个购买模块,那我这边可能要执行一个代码,比如减库存之类的东西,那我两个服务不就是要相互调用嘛,我自身是一个服务,我现在要调用减库存这个服务: 你调用它,你知道它一定能执行成功吗?肯定是不一定: 比如说,我现在要执行一个减库存的代码,我调用这个方法会进行库存的一个更改,这个库存减少成功还好,万一要是失败

  • 浅谈SpringBoot是如何实现日志的

    前言 休息日闲着无聊看了下 SpringBoot 中的日志实现,把我的理解跟大家说下. 门面模式 说到日志框架不得不说门面模式.门面模式,其核心为外部与一个子系统的通信必须通过一个统一的外观对象进行,使得子系统更易于使用.用一张图来表示门面模式的结构为: 简单来说,该模式就是把一些复杂的流程封装成一个接口供给外部用户更简单的使用.这个模式中,设计到3个角色. 1).门面角色:外观模式的核心.它被客户角色调用,它熟悉子系统的功能.内部根据客户角色的需求预定了几种功能的组合(模块). 2).子系统(

随机推荐