前后端业务分离时,可能有部署在不同域名下的需求。例如前端页面等资源部署在www.peterq.cn域名下,供用户访问,该域下的页面通过api.peterq.cn下的接口获取数据。但是浏览器会将这2个域名判断为异域,不做处理,www.peterq.cn无法获取api.peterq.cn下的数据。
“正宗”的跨域解决方案当然是采用CORS,不过这得需要服务器和浏览器支持,且有时还会多出一个options请求,加大服务器负载,延长响应时间,让人很不爽。对于主域名一致的子域之间跨域其实有更好的解觉办法。
在DOM中的domain
属性其实是可写的。当然并不是随意写,有限制,子域页面可以将其domain赋值成其父域,例如www.peterq.cn下的域名可执行document.domain = "peterq.cn"
,但修改成其他域,均会报错。利用这个特性便可以实现子域之间跨域了
1、www.peterq.cn下修改domain
为'peterq.cn'
在www.peterq.cn中输出的页面header里添加如下代码
<script>
document.domain= 'peterq.cn'
</script>
2、api.peterq.cn下修改domain
为'peterq.cn'
api.peterq.cn域下添加/cross路由,并输出如下内容
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<title>cross</title>
<script>
document.domain = 'peterq.cn'
function xhr(){
return new XMLHttpRequest()
}
</script>
</script>
</head>
<body>
</body>
</html>
3、在www.peterq.cn页面中嵌入iframe 引用//api.peterq.cn/cross
,并代理xhr
对象
在www.peterq.cn的页面中,所有的js代码之前添加如下js片段
<script>
document.write('<iframe src="//api.peterq.cn/cross" name="agent" style="display:none;"></iframe>')
var _XMLHttpRequest = window.XMLHttpRequest
window.XMLHttpRequest = function(){return agent.xhr()}
</script>
完成以上3步,就可以当作同域进行开发了,如果是已有项目,不需改动其他任何代码 :) 当然你得等到iframe,ready之后再实例化XMLHttpRequest
,因为此时agent.xhr
还是undefined
happy hacking~