Java前后端分离项目跨域问题解决方案
作者:庄周de蝴蝶
前言
本文将讲解前后端项目中跨域问题的常见解决方案,其中后端基于SpringBoot
,前端使用了jQuery
、axios
等框架用于实战代码的讲解。本文将不涉及跨域
的解释和SpringBoot
等框架,或者是Nginx
的使用,将主要讲解前后端分离项目中跨域问题的解决,不过如果你遇到了问题,也欢迎一起交流学习。
跨域解决
JSONP
方式
这种方式只能用于Get
请求,因此如果需要以Post
请求方式获取数据,则可以先看后面CORS
解决方式,以下就讲解两种基于JSONP
原理的解决方案,首先先看后端的接口:
@RestController @RequestMapping("/api/customer") public class HelloController { @GetMapping("/getAllCustomerInfo") public String getAllCustomerInfo() { // 返回的数据必须包含在 getAllCustomerInfo() 字符串中 // 以便在返回到前端后,可以自动执行回调函数,获取数据 // getAllCustomerInfo() 与前端的回调函数名对应 return "getAllCustomerInfo(" + getCustomerList() + ")"; } private String getCustomerList() { List<Customer> list = new ArrayList<>(Arrays.asList( new Customer(1, "张三", "123456"), new Customer(2, "李四", "654321"), new Customer(3, "王五", "123123") )); return new Gson().toJson(list); } }
下面就来分别讲解以下两种方式的解决方案:
js
原生解决方案
// 首先设置 src 并将结点添加到 <head> 中 const script = document.createElement('script') script.src = 'http://localhost:8080/api/customer/getAllCustomerInfo' document.head.appendChild(script) // 回调函数名与接口中返回的名字对应 const getAllCustomerInfo = res => { console.table(res, ['id', 'username', 'password']) }
通过以上设置就可以在Console
中看到以下结果:
jQuery
的ajax
解决方案
// 记得需要引入 jQuery <script src="https://cdn.staticfile.org/jquery/1.10.0/jquery.js"></script> $.ajax({ url: 'http://localhost:8080/api/customer/getAllCustomerInfo', type: 'get', dataType: 'jsonp', jsonpCallback: "getAllCustomerInfo" }) // 回调函数同上 const getAllCustomerInfo = res => { console.table(res, ['id', 'username', 'password']) }
CORS
解决方案
跨域资源共享(CORS) 是一种机制,它使用额外的 HTTP 头来告诉浏览器 让运行在一个 origin (domain) 上的Web应用被准许访问来自不同源服务器上的指定的资源。当一个资源从与该资源本身所在的服务器不同的域、协议或端口请求一个资源时,资源会发起一个跨域 HTTP 请求,详细解释请看链接。
后端接口中进行设置
通过利用CORS
,我们在前端只需要利用正常的ajax
请求方式即可,无需再设置回调函数,在这里我们使用了axios
,在展示后端代码之前,我们先看后端代码的改变,为了区别于JSONP
只能进行Get
请求,我们这里将接口改成了Post
:
@RestController @RequestMapping("/api/customer") public class HelloController { @PostMapping("/getAllCustomerInfo") public List<Customer> getAllCustomerInfo(HttpServletResponse response) { // 设置响应头 response.setHeader("Access-Control-Allow-Origin", "*"); // 不再需要将结果放在回调函数中 return new ArrayList<>(Arrays.asList( new Customer(1, "张三", "123456"), new Customer(2, "李四", "654321"), new Customer(3, "王五", "123123") )); } }
然后前端代码直接使用ajax
请求即可:
// 首先需要引入 axios <script src="https://cdn.staticfile.org/axios/0.1.0/axios.js"></script> axios.post('http://localhost:8080/api/customer/getAllCustomerInfo') .then(res => { console.table(res, ['id', 'username', 'password']) })
Nginx
反向代理
关于反向代理的知识,这里不做详细解析,感兴趣的话,可以查看该链接。通过使用Nginx
的反向代理,我们在后端接口中就可以去掉响应头的代码设置:
@RestController @RequestMapping("/api/customer") public class HelloController { @PostMapping("/getAllCustomerInfo") public List<Customer> getAllCustomerInfo() { return new ArrayList<>(Arrays.asList( new Customer(1, "张三", "123456"), new Customer(2, "李四", "654321"), new Customer(3, "王五", "123123") )); } }
然后是nginx.conf
中的修改:
server { # 监听80端口, 前端不再直接访问8080端口, 改为访问80端口即可 listen 80; server_name localhost; location / { root html; # 添加头 add_header Access-Control-Allow-Origin *; # 代理转发到8080后端端口 proxy_pass http://localhost:8080; index index.html index.htm; } }
然后再将前端中访问的接口修改为80:
// 首先需要引入 axios <script src="https://cdn.staticfile.org/axios/0.1.0/axios.js"></script> // 80为 http 默认端口,可省略 axios.post('http://localhost/api/customer/getAllCustomerInfo') .then(res => { console.table(res, ['id', 'username', 'password']) })
然后开启Nginx
服务器,Console
中再次出现了我们想看到的结果:
总结
本文并没有包括跨域问题的所有解决方案,不过相信对于大部分的跨域问题,都已经可以解决了,本文在之后也可能会继续更新,讲解更多种解决跨域问题的方法
到此这篇关于Java前后端分离项目跨域问题解决方案的文章就介绍到这了,更多相关Java前后端分离跨域内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!