跨越问题产生原因:产生跨域问题的原因是浏览器的同源策略,所谓同源是指:域名,协议,端口相同。如果不同,将会出现跨域问题。
一、创建项目
我们创建两个项目,一个命名为provider提供服务,一个命名为consumer消费服务,第一个项目端口配置为8080,第二个项目端口配置为8081,然后在provider中提供一个接口,供consumer项目里访问。
provider项目:
接口代码示例如下:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author qx
* @date 2023/06/17
* @desc 提供数据
*/
@RestController
public class HelloController {
/**
* 访问hello路径,返回hello字符串
*/
@GetMapping("/hello")
public String hello() {
return "hello";
}
}
consumer项目:
引入thymeleaf依赖,使用页面测试跨越问题。
<!--thymeleaf-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
消费者页面示例代码如下:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
/**
* @author qx
* @date 2023/06/17
* @desc 消费者页面
*/
@Controller
public class IndexController {
/**
* 访问/index路径打开index.html页面
*/
@GetMapping("/index")
public String toIndex() {
return "index";
}
}
index.html页面代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input type="button" onclick="btnClick()" value="click"/>
<script src="https://lib.baomitu.com/jquery/1.12.4/jquery.min.js"></script>
<script>
function btnClick() {
// 请求provider中的数据接口
$.get('http://localhost:8080/hello', function (msg) {
console.log(msg);
});
}
</script>
</body>
</html>
二、跨域问题产生
分别启动两个项目,点击consumer项目中index页面中的按钮。
我们发现没有成功访问到数据,页面控制台遇到了跨域访问的异常提示。
三、解决跨域
1.加@CrossOrigin注解
在provider项目的方法中加上@CrossOrigin注解,参数值为需要跨域访问的目标地址。
示例代码如下:
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author qx
* @date 2023/06/17
* @desc 提供数据
*/
@RestController
public class HelloController {
/**
* 访问hello路径,返回hello字符串
*/
@CrossOrigin(value = "http://localhost:8081/")
@GetMapping("/hello")
public String hello() {
return "hello";
}
}
表示这个方法可以接受来自http://localhost:8081/的请求,配置完成后重启provider项目,我们再次在consumer中发送请求,浏览器控制台不会报错,获取到了provider项目的数据。
2.跨域全局配置
在每个方法都加上@CrossOrigin很麻烦,我们在provider项目中通过在SpringMvc配置类中重写addCorsMappings实现全局的跨域配置。
示例代码如下:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author qx
* @date 2023/06/17
* @desc 全局跨域配置
*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:8081/")
.allowedMethods("*")
.allowedHeaders("*");
}
}
/**表示本应用的所有方法都会去处理跨域请求。
allowedOrigins表示可以跨域的目标访问地址。
allowedMethods表示允许通过的数。
allowedHeaders表示允许的请求头。
这样配置之后,我们就不必在每个方法上都单独的跨域配置了。
我们把provider项目中的@CrossOrigin注解去掉,重新启动provider项目。
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author qx
* @date 2023/06/17
* @desc 提供数据
*/
@RestController
public class HelloController {
/**
* 访问hello路径,返回hello字符串
*/
@GetMapping("/hello")
public String hello() {
return "hello";
}
}
我们继续点击consumer项目中index页面上的请求按钮,成功获取到了数据。