前端跨域

原创 黄灿灿 随笔 笔记 69阅读 27 天前 举报

前端与服务端数据交互时,涉及到跨域的一些问题。JavaScript出于安全的考虑,禁止了跨域调用其他页面的对象,也即同源策略限制了一个源(origin)中加载文本或脚本与来自其它源(origin)中资源的交互方式。

同源策略/SOP(Same origin policy)是一种约定,属于浏览器的一个安全功能。不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。所以a.com下的js脚本采用ajax读取b.com里面的文件数据是会报错的。

基于这个策略,有以下几种限制:

  • cookie:js不能读取其它域下的cookie,否则你的登录信息,安全信息就泄露了;
  • Storage和IndexDB: 道理同cookie;
  • DOM 和 JS 对象;
  • AJAX请求:不能发送另一个域下的Ajax请求;

什么是跨域?

如果违反了同源策略,则就会产生跨域。哪些情况才算是跨域呢?

  1. 页面域名不同: http://a.comhttp://b.com 不同源
  2. 父级域名相同,子域名不同: http://a.c.comhttp://b.c.com 不同源
  3. 端口不同:http://a.com:8888http://a.com:8000 不同源
  4. 协议不同: http://a.comhttps://a.com 不同源

解决跨域的方式

jsonp跨域
jsonp跨域的原理很简单,借鉴了html中script脚本可以来自不同域的原理。想一想是不是script中的src属性值可以设置为来自第三方的js。
但是这也限制了jsonp只能做GET请求,同时需要后端做配合。

举例说明:

有一个跨域的请求: http://c.com/getInfo?id=xxx。因为同源策略的限制,我们通过Ajax无法操作。那么使用jsonp,该如何绕过跨域的限制呢?直接看代码

这段代码中相对于我们刚才列出接口多了个参数cb=showInfo。这个参数值代表数据请求成功后回调方法,这个方法用于处理接口返回的数据。而在服务端,在返回数据时,要做一些处理。具体方式就是返回如何格式的数据:
showInfo(data)。
data就是通过接口想要获得数据。

JSONP的优点是:
它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;[1]
它的兼容性更好,在老版本的浏览器中可以运行,不需要XMLHttpRequest或ActiveX的支持;
它在请求完毕后可以通过调用callback的方式回传结果,方便调用。

JSONP的缺点则是:
它只支持GET请求而不支持POST等其它类型的HTTP请求,不能提交大量数据;
它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。

document.domain
如果两个源的父级域名一致,例如两个站点分别为http://a.c.com 和 http://b.c.com。 则可以通过设置window.domain = 'c.com'这样一来,他们的域也就相同了,可以互相操作。但是这种方式的缺点就是只适用于根域名一致的情况。也就是说,我们不可以将http://a.c.com的 window.domain设置为 d.com 或者 e.com之类的。只能设置为它根域名下的某个域。

document.domain + iframe
虽然通过document.domain的方式,我们只能在根域名一致的情况下进行跨域。但是如果配合iframe,则可以扩展我们的能力范围。例如:想要使a.com页面不跳转也能得到b.com里的数据。在a.com页面中使用一个隐藏的iframe来充当一个中间人角色,由iframe去获取b.com的数据,然后a.com再去得到iframe获取到的数据。

cros跨域解决方案
CORS:一种跨域访问的机制,可以让AJAX实现跨域访问;CORS允许一个域上的网络应用向另一个域提交跨域AJAX请求。 服务器设置Access-Control-Allow-Origin HTTP响应头之后,浏览器将会允许跨域请求. 就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功,还是应该失败。

目前绝大多数(除IE8及其以下版本)现代浏览器均支持CORS,移动端则是99%支持,所以在移动端开发时尽情享用吧,另外值得注意的是,对那些会对服务器数据造成破坏性影响的 HTTP 请求方法(特别是 GET 以外的 HTTP 方法,或者搭配某些MIME类型的POST请求),CORS标准强烈要求 浏览器必须先以 OPTIONS 请求方式发送一个预请求(preflight request),从而获知服务器端对跨源请求所支持 HTTP 方法。 在确认服务器允许该跨源请求的情况下,以实际的 HTTP 请求方法发送那个真正的请求。服务器端也可以通知客户端,是不是需要随同请求一起发送信用信息(包括 Cookies 和 HTTP 认证相关数据)。

与JSONP想比较,CORS支持所有类型的HTTP请求,且开发者可以使用原生普通的XMLHttpRequest对象发起请求和获得数据,配合新的JSAPI(fileapi、xhr2等)一起使用,实现强大的新体验功能。

Web sockets来跨域
同源策略对websocket请求不适用。
其原理:在JS创建了web socket之后,会有一个HTTP请求发送到浏览器以发起连接。取得服务器响应后,建立的连接会使用HTTP升级从HTTP协议交换为web sockt协议。

nginx转发
通过代理设置,进行转发,一样可以达到跨域的目的。

评论 ( 0 )
最新评论
暂无评论

赶紧努力消灭 0 回复