跨域

一个域下的文档或脚本去请求另一个域下的资源

广义的跨域:

1.资源跳转:A链接,重定向,表单提交;
2.资源嵌入:link,script,img,frame等dom标签,还有样式中的background:url(),@font-face() 等文件链接;
3.脚本请求:js发起的ajax请求,dom和js的跨域操作;

同源策略:

非同源限制:
1.cookie,LocalStorage,IndexDB无法读取;
2.DOM和JS对象无法获得;
3.ajax请求不能发送

跨域解决方案:

  • JSONP跨域

  • document.domain + iframe

  • location.hash + iframe

  • window.name + iframe

  • postMessage

  • 跨域资源共享(CORS)

  • nginx代理

  • nodejs中间件代理

  • WebSocketi协议

JSONP:

1.原生实现:

服务端返回如下(返回时即执行全局函数):

2.jquery ajax:

3.vue.js:

后端node.js代码示例:

jsonp缺点:只能实现get一种请求。

document.domain + iframe:

适用于主域名相同,子域不同

实现原理:两个页面都通过js强制设置document.domain为基础主域,就实现了同域。

注意:使用 document.domain 来允许子域安全访问其父域时,您需要在父域和子域中设置 document.domain 为相同的值。这是必要的,即使这样做只是将父域设置回其原始值。不这样做可能会导致权限错误。

1.)父窗口:(http://www.domain.com/a.html)

2.)子窗口:(http://child.domain.com/b.html)

location.hash + iframe:

a,b,c三个html互相通过iframe的hash传值

window.name + iframe跨域

window.name属性的独特之处:name值在不同的页面(甚至不同域名)加载后依旧存在,并且可以支持非常长的 name 值(2MB)

a.html:

proxy.html:中间代理页,与a.html同域,内容为空即可。

b.html:

总结:通过iframe的src属性由外域转向本地域,跨域数据即由iframe的window.name从外域传递到本地域。这个就巧妙地绕过了浏览器的跨域访问限制,但同时它又是安全操作。

跨域资源共享(CORS):

普通跨域请求:只服务端设置Access-Control-Allow-Origin即可,前端无须设置,若要带cookie请求:前后端都需要设置

前端设置

  • 原生ajax:

  • jquery ajax:

  • vue-resource:

服务端设置:

  • Java

  • nodejs Demo:

nginx代理跨域:

1、 nginx配置解决iconfont跨域

浏览器跨域访问js、css、img等常规静态资源被同源策略许可,但iconfont字体文件(eot|otf|ttf|woff|svg)例外,此时可在nginx的静态资源服务器中加入以下配置。

2、 nginx反向代理接口跨域

跨域原理: 同源策略是浏览器的安全策略,不是HTTP协议的一部分。服务器端调用HTTP接口只是使用HTTP协议,不会执行JS脚本,不需要同源策略,也就不存在跨越问题。

实现思路:通过nginx配置一个代理服务器(域名与domain1相同,端口不同)做跳板机,反向代理访问domain2接口,并且可以顺便修改cookie中domain信息,方便当前域cookie写入,实现跨域登录。

nginx具体配置:

1.) 前端代码示例:

2.) Nodejs后台示例:

Nodejs中间件代理跨域:

node中间件实现跨域代理与nginx类似,都是通过启动一个代理服务器,转发数据,也可以通过设置cookieDomainRewrite参数修改n响应头中cookie的中的域名,实现当前域的cookie的写入,方便接口登录认证。

1、 非vue框架的跨域(2次跨域)

利用node + express + http-proxy-middleware搭建一个proxy服务器。

1.)前端代码示例:

2.)中间件服务器:

3.)Nodejs后台同(六:nginx)

2、 vue框架的跨域(1次跨域)

利用node + webpack + webpack-dev-server代理接口跨域。在开发环境下,由于vue渲染服务和接口代理服务都是webpack-dev-server同一个,所以页面与代理接口之间不再跨域,无须设置headers跨域信息了。

webpack.config.js部分配置:

WebSocket协议跨域:

WebSocket protocol是HTML5一种新的协议。它实现了浏览器与服务器全双工通信,同时允许跨域通讯,是server push技术的一种很好的实现。

原生WebSocket API使用起来不太方便,我们使用Socket.io,它很好地封装了webSocket接口,提供了更简单、灵活的接口,也对不支持webSocket的浏览器提供了向下兼容

1.)前端代码:

2.)Nodejs socket后台:

参考链接:https://segmentfault.com/a/1190000011145364

Last updated

Was this helpful?