前后端分离的跨域问题

153 阅读3分钟

概述:

浏览器的同源策略导致了跨域问题,属于正常的保护机制“源”由协议、域名、端口号组成,正常的跨域情况:是当你访问了一个网站,然后这个网站返回的资源里面,请求了不同源网站的资源,于是就跨域了。而Postman工具不会跨域,因为浏览器才有同源策略的限制。

解决方式:

1.jsonp有安全隐患不做介绍

jsonp的原理就是利用<script>标签没有跨域限制,通过<script>标签src属性,只能发送 get 请求,服务器需要接收callback参数,返回函数调用

// 前端
$.ajax({
     type:"get",
             dataType:"jsonp",
             jsonp:"callback",//请求中重写回调函数的名字
             url:"http://127.0.0.1:8080/kexue/user",
             success:function (data) {
         alert(data.response);
     }
 }, 'json');
// 后端
@RequestMapping("/kexue/user")
public String demo(String callback) {
			JSONObject obj = JSONUtil.createObj();
			obj.put("code", 200);
			obj.put("response", "调用成功");
			// 返回格式:callback({object});
			return callback + "(" + obj + ")";
}

2.后端处理

CROS全称Cross-Origin Resource Sharing(跨域资源共享)。同源策略好比一个黑名单,这个黑名单非常严格,把所有的不同源客户端脚本都进行了限制访问,而CORS则是一个白名单,可以将允许访问的客户端脚本添加进这个白名单中。前端不需要做什么额外的事情。

浏览器有预检机制,在发出跨域请求前,浏览器自动发出一个查询请求,也叫预检请求,用来确认目标资源是否支持跨域,满足以下条件不发预检请求:
1.GetPostHead中的任意一个。
2.请求头包含AcceptContent-type、Width等字段。
3.Content-Type的值:text/plain、application/x-ww-form-urlencoded、multipart/form-data中的任意一个。
2.1 设置响应头

浏览器是根据响应头Access-Control-Allow-Origin这个字段来访问

...
    response.setHeader("Access-Control-Allow-Origin", "*");
...
2.2 @CrossOrigin注解

添加@CrossOrigin注解

...
    @CrossOrigin // 跨域注解
...
2.3 设置拦截器,重写cors接口`来实现等来实现

3.前端设置:Proxy代理

在脚手架vue、react中都可以配置代理

...
// 配置代理,如react中:
module.exports = function(app){
	app.use(
		proxy('/api1',{  //遇见api1的前缀的请求,就会促发代理配置
			target:'http://localhost:5000',  //请求转发给谁
			changeOrigin:true, // 控制服务器收到的请求头中host字段的值(配合target,欺骗服务器改变前缀)
			pathRewrite:{'^/api1':''} //重写请求路径,如:把/api1/students 替换成 /students
		})
	)
}

...

...
// 接口的调用
axios.get('http://localhost:3000/api1/students').then(
	.....
) 
// 如果3000端口没有这个请求,就走api配置的那个5000端口的代理,即执行结果相当于:http://localhost:5000/students
...

4.中转代理服务器:express \ nginx反向代理

如果不支持代理,手动创建一个中转服务器,比如express \ nginx反向代理,通过启一个代理服务器,实现数据的转发

如express操作
//1.下包 
npm install cors
//2.配置中间件 
var cors = require('cors') 
app.use(cors)

5.其他方案

5.1 postMessage跨域
5.2 WebSocket协议跨域