跨域

2017-12-31 Vaniot 更多博文 » 博客 » GitHub »

前端 后端

原文链接 https://vaniot-s.github.io/2017/12/31/%E8%B7%A8%E5%9F%9F/
注:以下为加速网络访问所做的原文缓存,经过重新格式化,可能存在格式方面的问题,或偶有遗漏信息,请以原文为准。


前端跨域

1.jsonp 原理: 标签不受同源测略 的限制,可以载入任意地方javascript文件,不要求同源 请求的文件

 <script\>
    function getWeather(data) {
        console.log(data);
    }
</script\>
<script src="http://x.y.com/xx.js" >
http://x.y.com/xx.js 文件内容:(返回调用getWeatherca参数为json对象数据)

输出文件:

 getWeather({
    "城市": "北京",
    "天气": "大雾"
});

<!--more--> 2.document.domain 使用条件: 有其他页面windowd对象的引用 二级域名相同 协议相同 端口相同

document.domain默认的值是整个域名,即使域名的二级域名一样,其document.domain是不相同的 将document.domain设置为二级域名


//打开 http://wenku.baidu.com/,在 console 中输入代码:
 document.domain = 'baidu.com';
var otherWindow = window.open('http://zhidao.baidu.com/');//打开百度知道的页面

我们现在已经发现百度知道的网页已经打开了,在百度知道网页的 console 中输入以下代码:

document.domain = 'baidu.com';

现在回到百度文库的网页,我们就可以使用百度知道网页的 window 对象来操作百度知道的网页了。例如:

var divs=otherWindow.document.getElementsByTagName('div');

3.window.name 在浏览器同一个标签中跳转,其window.name不会变化。window.name是string类型。 随意打开一个页面,输入以下代码:

window.name = "My window's name";
location.href = "http://www.qq.com/";

再检测 window.name :

window.name; // My window's name
 var iframe = document.getElementById('iframe');
var data = '';
iframe.onload = function() {
    iframe.onload = function(){
        data = iframe.contentWindow.name;
    }
    iframe.src = 'about:blank';
};

ps: about:blank,javascript: 和 data: 中的内容,继承了载入他们的页面的源。 postMessage [html5] postMessage 无视协议,端口,域名的不同

windowObj.postMessage(message, targetOrigin);

windowObj: 发送消息的 Window 对象 1.文档窗口中的iframe 2.JavaScript打开的弹窗 3.当前文档窗口的父窗口 4.打开当前文档的窗口(var win = window.opener();)。 message: 在最新的浏览器中可以是对象。 targetOrigin: 目标的源,* 表示任意(跳过发送消息u源的检测)。 接收消息:

var windowObj = window; // 可以是其他的 Window 对象的引用
var data = null;
addEventListener('message', function(e){
    if(e.origin == 'http://jasonkid.github.io/fezone') {
        data = e.data;     e.source.postMessage('Got it!', '*');
    }
});

message 事件就是用来接收 postMessage 发送过来的请求的。函数参数的属性有以下几个:

origin: 发送消息的 window 的源。
data: 数据。
source: 发送消息的 Window 对象。

服务器端的跨域

1.反向代理服务器 原理:将服务器配置为需要跨域的反向代理服务器,将其他域名的资源映射到自己的域名之下,让浏览器认为是同源的 2.CORS 浏览器支持

chorem firefox ie opera safari
4 3.5 8 & 9(XDomainRequest), 10 12

原理:服务器在响应头中设置相应的选项。 设置响应头信息:

Access-Control-Allow-Origin: <origin> | * //origin: 被允许跨域访问这个资源的网站,* 代表全部网站
Access-Control-Allow-Origin: http://jasonkid.github.io/fezone //允许 http://jasonkid.github.io/fezone 来跨域访问这个资源
是否允许浏览器携带 Cookie 来访问这个资源。

Access-Control-Allow-Credentials: true | false Access-Control-Allow-Credentials 属性要和 XMLHttpRequest 的 withCredentials 属性来配合使用。

var xhr = new XMLHttpRequest();
var url = 'http://foo.other/resources/credentialed-content/';

if(xhr) {
    xhr.open('GET', url, true);
    xhr.withCredentials = true; // 设置带有 Cookie 的资源请求
    xhr.onreadystatechange = handler;
    xhr.send(); 
}

能够成功使用带有 Cookie 的资源请求需要满足以下几个条件:

XMLHttpRequest 对象中指定了 withCredentials = true 服务器响应头中 Access-Control-Allow-Credentials: true 服务器响应头中 Access-Control-Allow-Origin 不能为 *

安全配置:

Access-Control-Expose-Headers
Access-Control-Allow-Methods
Access-Control-Allow-Headers