关于跨域

近期接到一个需要不同部门之间的web页面合作的项目,中间的接入方案涉及到跨域的方面,特记录如下:

我们部门,暂称A部门,域名www.domain1.com;兄弟部门,暂称B部门,域名www.domain2.com。

需求背景:A部门需要开发一个在线办公的独立web应用,但是没有在线编辑word,excel等office文件的相关工具,正好B部门开发了相关的在线编辑、导入、导出office文件的独立web应用,所以A部门需要B部门协助开发针对A部门的在线编辑工具

第一套方案:A部门负责前端编辑器代码+自己的独立web应用,B部门负责后端的解析存储服务+自己的独立web应用。

涉及到的跨域部分:A部门的前端---B部门的后端,即ajax跨域


第二套方案:A部门使用iframe套用B部门的独立web应用,各自负责自己独立的web应用

涉及到的跨域部分:A部门的前端--B部门的前端,js之间的跨域


OK,背景描述完了,现在看看,什么是跨域。跨域的产生是由于浏览器的同源策略导致的,那么什么是同源策略:

同源即相同协议,相同的域名【主域名与子域名不是相同的域名】,相同的端口。那么同源策略就是针对同源的客户端脚本在访问上存在限制,客户端脚本一般指javascript,至于vbscript什么的用的少,也就不说了,存在限制是指这个同源策略是W3C提出的,为的是保证不同源之前的安全性,但是不用的浏览器在实现上存在不同,这个可以针对下面讲到的几个方式具体用到了具体分析


那么同源策略都涉及到哪些具体影响呢?


1、ajax请求的URL必须与当前页面同源

2、不同源的页面之间的互相访问会受到限制,说白了,类似frame的结构,frame之间只提供有限的访问,具体有限到什么程度,可以看一下面这个url地址:

https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy

这是火狐官方对于同源的说明,算是比较通用的,具体来说呢就是,如果两个不同源的页面想要交互,只能通过window和window.location对象进行交互,其他方法要不就是访问,要不就是只提供只读访问

以上两个影响分别针对我们上面提到的两个实现方案,先说说第一个方案的ajax跨域3种实现方式:

1、CORS【跨域资源共享】,就是指在B部门的后端声明,如果是来自A部门的ajax请求,就通过。具体参数是:

Access-Control-Allow-Origin

1.1、可以在ngnix当中的response增加头部信息:addheader access-control-allow-origin:http://www.domain1.com,这样domain2.com就能为domain1提供后端服务支持。

优点:易处理,缺点:所有ngnix返回页面都会增加这种头,适合大量ajax跨域请求的情况。

1.2、还是这个参数,但是可以在具体页面的使用header,手动增加开关,下面是php的方式:

header('Access-Control-Allow-Origin:http://www.domain1.com');

优点:不会影响其他页面,比较独立,缺点:需要一个一个手动添加,适合少量ajax跨域请求的情况


具体实现:

www.domain1.com

<script>
    $(function(){

        var post_data = new Object();
        post_data.name = "test-cors";

        $.ajax({
            url: 'http://www.domain2.com/cors/',
            //type:'POST',
            type:'GET',
            dataType:'json',
            data:post_data,
            success:function(response){
               alert(response);
            }
        });
    });
</script>

www.domain2.com

header('Access-Control-Allow-Origin:http://www.domain1.com');
echo json_encode($_REQUEST['name']);

或者设置ngnix:

location / {
 add_header Access-Control-Allow-Origin http://www.domain1.com
}

2、JSONP

JSONP的原理是什么,原理是由于在同源策略当中设定了页面的dom结构当中有部分语法是不受跨域影响的,同样是摘自火狐官方的一段话:

Here are some examples of resources which may be embedded cross-origin:

  • JavaScript with <script src="..."></script>. Error messages for syntax errors are only available for same-origin scripts.
  • CSS with <link rel="stylesheet" href="...">. Due to the relaxed syntax rules of CSS, cross-origin CSS requires a correct Content-Typeheader. Restrictions vary by browser: IEFirefoxChromeSafari (scroll down to CVE-2010-0051) and Opera.
  • Images with <img>. Supported image formats include PNG, JPEG, GIF, BMP, SVG, ...
  • Media files with <video> and <audio>.
  • Plug-ins with <object><embed> and <applet>.
  • Fonts with @font-face. Some browsers allow cross-origin fonts, others require same-origin fonts.
  • Anything with <frame> and <iframe>. A site can use the X-Frame-Options header to prevent this form of cross-origin interaction
JSONP其实就是利用到了这点,即script标签,如果我的前端页面是引用了一个前端页面,然后这个前端页面其实是后端页面生成的JS代码块呢?那么我的前端页面就可以使用了这段代码块了

www.domain1.com
<script>
    function show(name){
        alert(name);
    }
</script>
<script src="http://www.domain2.com/jsonp/index.php?callback=show"></script>

www.domain2.com
header('Content-Type: text/javascript');
$callback = $_GET['callback'];

$name = 'test-jonp';
echo $callback."('$name')";

这样www.domain2.com实际返回的是一段儿javascript代码块:show('test-jonp')
返回到www.domain1.com,由于show方法已经声明过了,所以就会成功的调用show方法完成跨域


3、其他




火狐:https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy

Cross-origin script API access

JavaScript APIs such as iframe.contentWindowwindow.parentwindow.open and window.opener allow documents to directly reference each other. When the two documents do not have the same origin, these references provide very limited access to Window and Location objects, as described in the next two sections.

To communicate further between documents from different origins, use window.postMessage.

Window

Specification:  http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#security-window.

The following cross-origin access to Window properties is allowed:

Methods
window.blur
window.close
window.focus
window.postMessage
Attributes  
window.closed Read only.
window.frames Read only.
window.length Read only.
window.location Read/write.
window.opener Read only.
window.parent Read only.
window.self Read only.
window.top Read only.
window.window Read only.

Some browsers allow access to more properties than the specification allows.

Location

Specification:  http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#security-location.

The following cross-origin access to Location properties is allowed:

Methods
location.replace
Attributes  
URLUtils.href Write only.
https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage

Browser compatibility

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari (WebKit)
Basic support 1.0 6.0 (6.0)[1]
8.0 (8.0)[2]
8.0[3]
10.0[4]
9.5 4.0
transferargument ? 20.0 (20.0) Not supported ? ?


在 Webkit 的 Document.idl 源码中对 domain 有这样的定义:

#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
    [TreatNullAs=NullString, SetterRaisesException] attribute DOMString domain;
#else
    readonly attribute DOMString domain;
#endif

这也说明了 domain 设置为“writable” 仅用于页面脚本:即允许主子域脚本进行通信,但不涉及 localStorage 、indexedDB 和 XMLHttpRequest 的共享。目前市场上主流浏览器都支持 domain可写,可以满足几乎所有主子域脚本通信需求,但在特殊情况下也有些许不同

http://yanni4night.com/blog/setting-document-domain.html


location.hash 是什么:
hash 属性是一个可读可写的字符串,该字符串是 URL 的锚部分(从  # 号开始的部分)
location.hash原理:
1、动态改变location.hash,iframe不会重载
2、无论跨域与否,iframe内可以获取自己的location.hash

3、只要域名相同就能通信,即使ABC三层嵌套


window.name
window.name 是什么:
name 在浏览器环境中是一个全局window对象的属性
当在 iframe 中加载新页面时,name 的属性值依旧保持不变
name 属性仅对相同域名的 iframe 可访问
window.name 的优势:
数据量更大(2M)
更安全
可传递多种数据格式
window.name 的劣势:
只适用于隐藏iframe的情形


window.name 传输技术,原本是 Thomas Frank 用于解决 cookie 的一些劣势(每个域名 4 x 20 Kb 的限制、数据只能是字符串、设置和获取 cookie 语法的复杂等等)而发明的(详细见原文:《Session variables without cookies》),后来 Kris Zyp 在此方法的基础上强化了 window.name 传输 ,并引入到了 Dojo dojox.io.windowName),用来解决跨域数据传输问题。

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

http://www.planabc.net/2008/09/01/window_name_transport/


https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/The_structured_clone_algorithm

Supported types

Object type Notes
All primitive typesHowever not symbols
Boolean object 
String object 
Date 
RegExpThe lastIndex field is not preserved.
Blob 
File 
FileList 
ArrayBuffer 
ArrayBufferViewThis basically means all typed arrays like Int32Array etc.
ImageData 
Array 
ObjectThis just includes plain objects (e.g. from object literals)
Map 
Set 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值