前后端分离项⽬跨域问题解决⽅案总结
前⾔
本⽂将讲解前后端项⽬中跨域问题的常见解决⽅案,其中后端基于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);
}
}
下⾯就来分别讲解以下两种⽅式的解决⽅案:
1. js原⽣解决⽅案
// ⾸先设置 src 并将结点添加到 <head> 中
const script = ateElement('script')
script.src = 'localhost:8080/api/customer/getAllCustomerInfo'
document.head.appendChild(script)
/
/ 回调函数名与接⼝中返回的名字对应
const getAllCustomerInfo = res => {
console.table(res, ['id', 'username', 'password'])
}
通过以上设置就可以在Console中看到以下结果:
2. jQuery的ajax解决⽅案
// 记得需要引⼊ jQuery
<script src="/jquery/1.10.0/jquery.js"></script>
$.ajax({
nginx部署前端项目url: 'localhost:8080/api/customer/getAllCustomerInfo',
type: 'get',
dataType: 'jsonp',
jsonpCallback: "getAllCustomerInfo"
})
// 回调函数同上
const getAllCustomerInfo = res => {
console.table(res, ['id', 'username', 'password'])
}
CORS解决⽅案
跨域资源共享() 是⼀种机制,它使⽤额外的头来告诉浏览器让运⾏在⼀个 origin (domain) 上的Web应
⽤被准许访问来⾃不同源服务器上的指定的资源。当⼀个资源从与该资源本⾝所在的服务器不同的域、协议或端⼝请求⼀个资源时,资源会发起⼀个跨域 HTTP 请求,详细解释请看。
1. 后端接⼝中进⾏设置
通过利⽤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="/axios/0.1.0/axios.js"></script>
axios.post('localhost:8080/api/customer/getAllCustomerInfo')
.then(res => {
console.table(res, ['id', 'username', 'password'])
})
2. 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")
));
}
}
然后是f中的修改:
server {
# 监听80端⼝, 前端不再直接访问8080端⼝, 改为访问80端⼝即可
listen 80;
server_name localhost;
location / {
root html;
# 添加头
add_header Access-Control-Allow-Origin *;
# 代理转发到8080后端端⼝
proxy_pass localhost:8080;
index index.html index.htm;
}
}
然后再将前端中访问的接⼝修改为80:
// ⾸先需要引⼊ axios
<script src="/axios/0.1.0/axios.js"></script>
// 80为 http 默认端⼝,可省略
axios.post('localhost/api/customer/getAllCustomerInfo')
.then(res => {
console.table(res, ['id', 'username', 'password'])
})
然后开启Nginx服务器,Console中再次出现了我们想看到的结果:
总结
本⽂并没有包括跨域问题的所有解决⽅案,不过相信对于⼤部分的跨域问题,都已经可以解决了,本⽂在之后也可能会继续更新,讲解更多种解决跨域问题的⽅法,也欢迎各位⼀起交流学习。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论