跨域问题是在浏览器端在当下域名(源)试图访问其他域名(非同源)的资源产生的,同源策略(协议、域名、端口相同)是浏览器的安全机制。跨域问题可以说是一个很常见的问题,如今很多服务都微化了,很容易遇到跨域的问题。
常见的解决方案就是jsonp(后端包装js回调)和CORS(后端跨域共享)。
先来看下jsonp,利用src属性加载静态资源不受跨域限制,比如使用script标签引入js文件,使用img加载图片。原理就是通过src来请求非同源资源并指定callback函数,后端收到请求后包装callback函数和响应结果给前端,前端收到结果后触发页面的callback回调函数。
<div id="jsonp"></div>
<div id="button"><input type="button" onclick="jsonpData()" value="jsonp我"/></div>
<script>
function jsonpData() {
$.ajax({
type: "GET",
//dataType: "jsonp",
url: "http://localhost:9000/hello/jsonp",
success: function (data) {
$("#jsonp").html(data.data);
}
});
}
</script>
如图我们在端口9001的页面中请求端口9000的资源,直接请求会产生如下错误:
后台包装后重新返回前端数据,注意后端处理后才能触发前端事件
@GetMapping("jsonp")
public void helloJsonp(HttpServletRequest req, HttpServletResponse resp){
String callback = req.getParameter("callback");
String result = "{\"data\":\"hello jsonp!!!\"}";
try {
result = callback + "(" + result + ")";
resp.getWriter().write(result);
} catch (IOException e) {
e.printStackTrace();
}
}
如下可以正常请求了:
下面看下使用CORS,由后端宣布跨域资源共享,前端页面无需多做处理,正常发起请求即可,项目示例(springboot2)。
Controller
@RequestMapping("hello")
@CrossOrigin(value = "http://localhost:9001")
public class HelloController {
@GetMapping("cors")
@ResponseBody
public String helloCors(){
return "hello cors!!!";
}
只需要添加注解@CrossOrigin即可,注解可以配置在类上,也可以单独配置在接口上。当然这里也可以实现全局的WebMvcConfigurer,添加指定的cors配置。
jsonp是常见的跨域处理方式,只能支持get请求(很好理解,通过src请求资源),需要后端配合返回回调函数,在前端页面触发回调函数。cors不限于请求方式(put方式会产生两次数据请求)。
觉得有用,点个关注: