跨域目前是广大开发者经常遇到的一个问题.在此我将几种常用的解决方案介绍一下
1:JSONP
JSONP 是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,缺点是只支持get请求,不支持post请求。
1.1 Jquery版本:
$.ajax({
url:'http://www.test.cn/login',
type:'GET',
dataType:'jsonp', //请求方式为jsonp
jsonpCallback:'callback', // 自定义回调函数名
data:{
"username":"Nealyang"
}
})
1.2: vue版本
this.$http.jsonp('http://www.test.com:8080/login', {
params: {},
jsonp: 'handleCallback'
}).then((res) => {
console.log(res);
})
jsonp这种方式,使用起来非常简单.就是将请求方式改为jsonp就行了
2:CORS
cors目前是使用最广泛的一种跨域解决方案,它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
2.1:java服务端代码:
private void crossDomain(HttpServletResponse resp) {
resp.setHeader("Content-type", "text/html;charset=UTF-8");
resp.setCharacterEncoding("UTF-8");
// *代表所有请求都可访问
resp.setHeader("Access-Control-Allow-Origin", "*");
resp.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS,, PUT, DELETE, TRACE, PATCH");
resp.setHeader("Access-Control-Allow-Headers", "Origin, No-Cache, X-Requested-With, " +
"If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With");
}
cors只需要java服务端进行处理即可,前端正常发送请求就行.
2.2:CORS的两种状态
既然使用了CORS还是需要理解下CORS的两种状态. 它有两种情况,一种是简单请求,一种是非简单请求.
只要同时满足以下两大条件,就属于简单请求。否则就是非简单请求。
(1) 请求方法是以下三种方法之一:
- HEAD
- GET
- POST
(2)HTTP的头信息不超出以下几种字段:
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- Content-Type:只限于三个值
application/x-www-form-urlencoded
、multipart/form-data
、text/plain
2.3:简单请求
具体来说,浏览器自动在头信息之中,增加一个Origin
字段。
Origin
字段用来说明,本次请求来自哪个源(协议 + 域名 + 端口)。服务器根据这个值,决定是否同意这次请求。
2.4:非简单请求
当发生非简单请求(预检请求)的条件时,浏览器会自动先发送一个options请求,如果发现服务器支持该请求,则会将真正的请求发送到后端,反之,如果浏览器发现服务端并不支持该请求,则会在控制台抛出错误,如下:
如果非简单请求(预检请求)发送成功,则会在头部多返回以下字段
Access-Control-Allow-Origin: http://localhost:3001 //该字段表明可供那个源跨域
Access-Control-Allow-Methods: GET, POST, PUT // 该字段表明服务端支持的请求方法
Access-Control-Allow-Headers: X-Custom-Header // 实际请求将携带的自定义请求首部字段
3:总结jsonp与CORS的对比
使用CORS简单请求,非常容易,对于前端来说无需做任何配置,只需要后端做处理即可,与发送普通ajax请求无异。唯一需要注意的是,需要携带cookie信息时,需要将withCredentials设置为true即可。
使用jsonp请求,需要前端进行处理,并且只支持GET请求.