概述:
浏览器的同源策略导致了跨域问题,属于正常的保护机制,“源”由协议、域名、端口号组成,正常的跨域情况:是当你访问了一个网站,然后这个网站返回的资源里面,请求了不同源网站的资源,于是就跨域了。而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.Get、Post、Head中的任意一个。
2.请求头包含Accept、Content-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)