Java前后端分离项目跨域问题解决方案

 更新时间:2024年03月12日 09:02:54   作者:庄周de蝴蝶  
本文主要介绍了Java前后端分离项目跨域问题解决方案,其中后端基于SpringBoot,前端使用了jQuery、axios等框架,具有一定的参考价值,感兴趣的可以了解一下

前言

本文将讲解前后端项目中跨域问题的常见解决方案,其中后端基于SpringBoot,前端使用了jQueryaxios等框架用于实战代码的讲解。本文将不涉及跨域的解释和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中看到以下结果:

image-20200915142859045

jQueryajax解决方案

// 记得需要引入 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中再次出现了我们想看到的结果:

image-20200915150523876

总结

本文并没有包括跨域问题的所有解决方案,不过相信对于大部分的跨域问题,都已经可以解决了,本文在之后也可能会继续更新,讲解更多种解决跨域问题的方法

到此这篇关于Java前后端分离项目跨域问题解决方案的文章就介绍到这了,更多相关Java前后端分离跨域内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解Spring Boot Junit单元测试

    详解Spring Boot Junit单元测试

    本篇文章主要介绍了详解Spring Boot Junit单元测试,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • SpringBoot与单元测试JUnit的结合操作

    SpringBoot与单元测试JUnit的结合操作

    这篇文章主要介绍了SpringBoot与单元测试JUnit的结合操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • 细数java中Long与Integer比较容易犯的错误总结

    细数java中Long与Integer比较容易犯的错误总结

    下面小编就为大家带来一篇细数java中Long与Integer比较容易犯的错误总结。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-01-01
  • 这一次搞懂Spring代理创建及AOP链式调用过程操作

    这一次搞懂Spring代理创建及AOP链式调用过程操作

    这篇文章主要介绍了这一次搞懂Spring代理创建及AOP链式调用过程操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • java蓝桥杯历年真题及答案整理(小结)

    java蓝桥杯历年真题及答案整理(小结)

    这篇文章主要介绍了java蓝桥杯历年真题及答案整理(小结),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02
  • SpringMVC表单标签使用详解

    SpringMVC表单标签使用详解

    这篇文章主要为大家详细介绍了SpringMVC表单标签的使用方法,教大家如何用Spring封装的一系列表单标签
    2017-03-03
  • MyBatis反向生成Example类的使用方式

    MyBatis反向生成Example类的使用方式

    今天小编就为大家分享一篇MyBatis反向生成Example类的使用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • 使用springmvc参数接收boolean类型参数的问题

    使用springmvc参数接收boolean类型参数的问题

    这篇文章主要介绍了使用springmvc参数接收boolean类型参数的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • java中如何截取字符串最后一位

    java中如何截取字符串最后一位

    这篇文章主要介绍了java中如何截取字符串最后一位的实现方法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • springboot集成elasticsearch7的图文方法

    springboot集成elasticsearch7的图文方法

    本文记录springboot集成elasticsearch7的方法,本文通过图文实例代码相结合给大家介绍的非常详细,需要的朋友参考下吧
    2021-05-05

最新评论