当前位置 博文首页 > 编程小马:一文带你彻底搞懂JS前端跨域请求
常见的跨域场景如下:
源 URL | 请求 URL | 是否跨域 | 说明 |
---|---|---|---|
http://mcy.com/a | http://mcy.com/b | 否 | 同协议同域名同端口号,不同请求,不算跨域请求 |
http://mcy.com/a | http://mcy.com:8080/b | 是 | 端口不同 |
http://mcy.com/a | https://mcy.com/b | 是 | 协议不同 |
http://www.mcy.com/a | http://mcy.a.com/b | 是 | 主域名相同,但是子域名不相同 |
http://mcy.com/a | http://abc.com/b | 是 | 域名不相同 |
通常为了减轻web服务器的负载,我们可以引入其他服务器上的js、css,img等静态资源,在html页面中再通过相应的标签从不同域名下加载静态资源,而被浏览器允许,基于此原理,我们可以通过动态创建script,再请求一个带参网址实现跨域请求。
1、原生实现
var script = document.createElement('script');
script.type = 'text/javascript';
// 传参并指定回调执行函数为onBack
script.src = 'http://machaoyin.top:8080/user/findById?id=1&callback=back';
document.head.appendChild(script);
// 回调执行函数
function back(data) {
console.log(data);
}
原生实现除了这样写,还可以自己使用script标签请求,具体代码如下;
// 回调执行函数
function back(data) {
console.log(data);
}
//跨域请求
<script src="http://machaoyin.top:8080/user/findById?id=1&callback=back"></script>
后端返回方法(根据id查询数据)
@GetMapping(value = "findById")
@ApiOperation(value = "根据id获取用户信息", notes = "根据id查询用户信息")
public String getUser(Integer id, HttpServletRequest request, HttpServletResponse response){
String callback = (String)request.getParameter("callback");
User user = userService.findById(id);
JSONObject jsonObject = JSONObject.fromObject(user);
String retStr = callback + "(" + jsonObject + ")";
return retStr;
}
返回查询的对象数据。其中使用JSONObject把JavaBean对象转为json字符串。JSONObject的使用请移步:浅谈JSONObject的使用
测试代码中请求的地址为我服务器地址,后端请求接口方法使用的Swagger来维护接口规范,详情请访问:SpringBoot整合Swagger2
请求的结果如图:
2、Jquery AJAX实现
$.ajax({
url: 'http://machaoyin.top:8080/user/findById?id=1',
type: 'get',
dataType: 'jsonp', // 请求方式为jsonp
success:function(data){
console.log(data);
}
});
【注】返回结果和原生实现返回的一样。使用jsonp很方便也很简单,但有一个缺点就是只能发送get请求,AJAX设置post方法也是发送get请求。
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。它允许浏览器向跨源(协议 + 域名 + 端口)服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同域使用的限制。
CORS需要浏览器和服务器同时支持。它的通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX/Fetch通信没有差别,代码完全一样。浏览器一旦发现请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。因此,实现CORS通信的关键是服务器。只要服务器端实现了CORS接口,就可以跨域请求。
后端CORS接口案例:
@CrossOrigin(origins = "*")
@PostMapping(value = "/find")
@ApiOperation(value = "根据id获取用户信息", notes = "根据id查询用户信息")
public User find(Integer id){
return userService.findById(id);
}
在SpringMVC中可以直接使用注解@CrossOrigin来解决跨域接口的问题。
@CrossOrigin有两个参数
web项目中可以通过HttpServletResponse 来设置,具体代码如下:
@RequestMapping(value = "/find")
@ApiOperation(value = "根据id获取用户信息", notes = "根据id查询用户信息")
public User find(Integer id, HttpServletResponse res){
//允许请求的地址
res.setHeader("Access-Control-Allow-Origin", "*");
//请求方式,也可以在请求注解上设置
res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
//最长响应时间
res.setHeader("Access-Control-Max-Age", 60);
return userService.findById(id);
}
前台跨域请求不需要任何改变,和平常的AJAX请求一样即可,如下:
$.ajax({
url: 'http://machaoyin.top:8080/user/find?id=1',
type: 'post',
success: function(data){
console.log(data);
}
});
请求结果和上面的一样,这里就不多展示了。
【注】 jsonp跨域请求和跨域资源共享 CORS最大区别在也jsonp只能发送get请求,而CORS可以发送http的任一请求类型。
cs最后有什么不足之处,欢迎大家指出,期待与你的交流。如果感觉对你有帮助,点个赞在走呗 O(∩_∩)O ~