欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

计算机基础:域名以及跨域

程序员文章站 2024-02-29 19:19:10
...

域名基础知识:

      一个完整的域名由二个或二个以上部分组成,各部分之间用英文的句号"."来分隔,最后一个"."的右边部分称为*域名(TLD,也称为一级域名),最后一个"."的左边部分称为二级域名(SLD),二级域名的左边部分称为三级域名,以此类推,每一级的域名控制它下一级域名的分配。定义是这样的,在域名中包含两个点的,就叫二级域名,只包含一个点的,就是一级域名。

       域名级数是指一个域名由多少级组成,域名的各个级别被“.”分开,简而言之,有多少个点就是几级域名。

      *域名在开头有一个点,一级域名就是在“com net org”前加一级:http://www.cdxwcx.com/(前面是www的通用网址)

      二级域名就是在一级域名前再加一级:http://domain.cdxwcx.com/(www替换成了别的)

      二级域名及其以上级别的域名,统称为子域名,不在“注册域名”的范畴中。

      中间由点号分隔开,最右边的那个词称为*域名。

      (!补充: 也就是说www只是一个主机名,真正的一级域名是由一个合法字符串+域名后缀组成。)

一级域名又叫*域名,就像我们现在的网站建设网站网址 http://cdxwcx.com/ 是一级域名 如果http://domain.cdxwcx.com/ 就是二级域名了。

四种跨域方法:

1. JSONP

首先要介绍的跨域方法必然是 JSONP。

现在你想要获取其他网站上的 JavaScript 脚本,你非常高兴的使用 XMLHttpRequest 对象来获取。但是浏览器一点儿也不配合你,无情的弹出了下面的错误信息:

XMLHttpRequest cannot load http://x.com/main.dat. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://y.com' is therefore not allowed access.

为了避免这种蛋疼的事情发生,JSONP 就派上用场了。你心里肯定会想,我难道要用后台做个爬虫来获取这个数据吗?!

<script>  标签是不受同源策略的限制的,它可以载入任意地方的 JavaScript 文件,而并不要求同源。

所以 JSONP 的理念就是,我和服务端约定好一个函数名,当我请求文件的时候,服务端返回一段 JavaScript。这段 JavaScript 调用了我们约定好的函数,并且将数据当做参数传入。

非常巧合的一点(其实并不是),JSON 的数据格式和 JavaScript 语言里对象的格式正好相同。所以在我们约定的函数里面可以直接使用这个对象。

你需要获取数据的页面 index.html:

<script>

    function getWeather(data) {

        console.log(data);

    }

</script>

<script src="http://x.y.com/xx.js">

http://x.y.com/xx.js 文件内容:

JavaScript

getWeather({

    "城市": "北京",

    "天气": "大雾"

});

我们可以看到,在我们定义了 getWeather(data)  这个函数后,直接载入了 xx.js。

在这个脚本中,执行了  getWeather  函数,并传入了一个对象。然后我们在这个函数中将这个对象输出到 console 中。

这就是整个 JSONP 的流程。

2. document.domain

使用条件:

  1. 有其他页面 window 对象的引用。
  2. 二级域名相同。
  3. 协议相同。
  4. 端口相同。

document.domain  默认的值是整个域名,所以即使两个域名的二级域名一样,那么他们的document.domain 也不一样。

使用方法就是将符合上述条件页面的 document.domain 设置为同样的二级域名。这样我们就可以使用其他页面的 window 对象引用做我们想做的任何事情了。

补充知识:

  • x.one.example.com 和 y.one.example.com 可以将 document.domain 设置为 one.example.com,也可以设置为 example.com。
  • document.domain  只能设置为当前域名的一个后缀,并且包括二级域名或以上(.edu.cn 这种整个算*域名)。

我们直接操刀演示,用两个网站 http://wenku.baidu.com/ 和 http://zhidao.baidu.com/

这两个网站都是 http 协议,端口都是 80, 且二级域名都是 baidu.com。

打开 http://wenku.baidu.com/,在 console 中输入代码:

JavaScript

document.domain = 'baidu.com';

var otherWindow = window.open('http://zhidao.baidu.com/');

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

JavaScript

document.domain = 'baidu.com';

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

JavaScript

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

上面这个例子的使用方法并不常见,但是非常详细的说明了这种方法的原理。

这种方法主要用在控制  <iframe>  的情况中。

比如我的页面(http://one.example.com/index.html)中内嵌了一个 <iframe> :

<iframe id="iframe" src="http://two.example.com/iframe.html"></iframe>

我们在 iframe.html 中使用 JavaScript 将  document.domain  设置好,也就是 example.com。

在 index.html 执行以下脚本:

JavaScript

var iframe = document.getElementById('iframe');

document.domain = 'example.com';

iframe.contentDocument; // 框架的 document 对象

iframe.contentWindow; // 框架的 window 对象

这样,我们就可以获得对框架的完全控制权了。

补充知识(绝对干货):

当两个页面不做任何处理,但是使用了框架或者 window.open() 得到了某个页面的 window 对象的引用,我们可以直接访问的属性有哪些?

方法

window.blur

window.close

window.focus

window.postMessage

window.location.replace

属性

权限

window.closed

只读

window.frames

只读

window.length

只读

window.location.href

只写

window.opener

只读

window.parent

只读

window.self

只读

window.top

只读

window.window

只读

3. window.name

我们来看以下一个场景:

随意打开一个页面,输入以下代码:

JavaScript

dow.name = "My window's name";

location.href = "http://www.qq.com/";

再检测  window.name  :

JavaScript

window.name; // My window's name

可以看到,如果在一个标签里面跳转网页的话,我们的 window.name 是不会改变的。

基于这个思想,我们可以在某个页面设置好 window.name  的值,然后跳转到另外一个页面。在这个页面中就可以获取到我们刚刚设置的 了。

由于安全原因,浏览器始终会保持 window.name 是 string 类型。

这个方法也可以应用到与 <iframe> 的交互上来。

我的页面(http://one.example.com/index.html)中内嵌了一个  <iframe>  :

<iframe id="iframe" src="http://omg.com/iframe.html"></iframe>

在 iframe.html 中设置好了  window.name  为我们要传递的字符串。

我们在 index.html 中写了下面的代码:

JavaScript

var iframe = document.getElementById('iframe');

var data = '';

iframe.onload = function() {

    data = iframe.contentWindow.name;

};

定睛一看,为毛线报错?

细心的读者们肯定已经发现了,两个页面完全不同源啊!

由于 window.name 不随着 URL 的跳转而改变,所以我们使用一个暗黑技术来解决这个问题:

JavaScript

var iframe = document.getElementById('iframe');

var data = '';

iframe.onload = function() {

    iframe.onload = function(){

        data = iframe.contentWindow.name;

    }

    iframe.src = 'about:blank';

};

或者将里面的 about:blank 替换成某个同源页面(最好是空页面,减少加载时间)。

补充知识:

about:blank , javascript: 和 data: 中的内容,继承了载入他们的页面的源。

这种方法与 document.domain 方法相比,放宽了域名后缀要相同的限制,可以从任意页面获取 string 类型的数据。

4. [HTML5] postMessage

在 HTML5 中, window 对象增加了一个非常有用的方法:

JavaScript

windowObj.postMessage(message, targetOrigin);
  • windowObj : 接受消息的 Window 对象。
  • message : 在最新的浏览器中可以是对象。
  • targetOrigin : 目标的源,* 表示任意。

这个方法非常强大,无视协议,端口,域名的不同。下面是烤熟的栗子:

JavaScript

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 对象。

相关标签: 计算机基础