Monthly Archives: January 2013

跨域iframe自适应高度

这个可能是一个老生常谈的问题了,搜索google和百度应该也是文章大把大把的;处理方式也大同小异,今天又有哥们问这个问题,所以还是将自己的处理方式写出来。

最早遇到这个问题是07年在Yahoo的时候,当时SNS盛行,Yahoo也决定做SNS,其中就有应用是iframe模式的,但是iframe的页面在对方服务器上,使用的也是别人的域名,Yahoo也不可能给对方提供二级或三级域名;那就遇到一个问题,怎样去调整iframe的高度,让他做到自适应;大家都知道JS为了安全,是不能跨域执行的,所以只能通过其他方式实现;感谢克军同学当时给的建议。

下面具体说说怎么实现吧。

首先因为iframe是跨域的,所以不能直接用JS来控制,只能通过一个中间键,我们这里选择在iframe的页面(页面B)中再iframe一个父页面(页面A)同域的页面(页面C);这样页面C就能和页面A进行无障碍的通讯了;因为页面B iframe 页面C,所以页面B可以改写页面C的href值;到这里大家应该看明白啥意思了,来张图说明下:
iframe

A页面中的内容

A页面主要就是接收C页面传过来的内容并且去完成相应的操作。可能有人会说直接C页面来操作不就可以了?但是那样处理不太好,因为可能A页面中还有很多其他的公共方法,比如美化过的Alert等,所以如果能做一个公共的方法来接收C页面传过来的值会更加方便之后的框架调整,而且也不建议总是去修改页面C。

<iframe id="ifr" src="iframe_b.html" height="200" width="400"></iframe>
<script type="text/javascript">
var ifr_el = document.getElementById("ifr");
function getIfrData(data){
    ifr_el.style.height = data+"px";
}
</script>

B页面中的内容

B页面的主要内容当然是怎么把值传递给C页面,前面说了是将值传递到C页面的href中,所以只要修改iframe的src就可以,因为不用刷新C页面,所以可以用过hash的方式传递给C页面

<div id="box">
	<button id="btn_auto" type="button">Height Auto: off</button>
	<button id="btn_plus10" type="button">Height +10px</button>
	<button id="btn_minus10" type="button">Height -10px</button>
</div>
<iframe id="ifr" src="iframe_c.html" width="0" height="0"></iframe>
<script type="text/javascript">
var box_el = document.getElementById("box"),
    btn_auto_el = document.getElementById("btn_auto"),
    btn_plus10_el = document.getElementById("btn_plus10"),
    btn_minus10_el = document.getElementById("btn_minus10"),
    ifr_el = document.getElementById("ifr");

var isAuto = false,
    oldHeight = 0,
    ifrSrc = ifr_el.src.split("#")[0];

btn_auto_el.onclick = function(){
	if(!isAuto){
		isAuto = true;
		btn_auto_el.innerHTML = "Height Auto: on";
	}else{
		isAuto = false;
		btn_auto_el.innerHTML = "Height Auto: off";
	}
}
btn_plus10_el.onclick = function(){
	var height = box_el.offsetHeight;
	box_el.style.height = (10+height)+"px";
}
btn_minus10_el.onclick = function(){
	var height = box_el.offsetHeight;
	box_el.style.height = (height-10)+"px";
}
setInterval(function(){
	if(isAuto){
		var height = document.body.scrollHeight;
		height += 20;
		if(oldHeight != height){
			oldHeight = height;
			ifr_el.src = ifrSrc+"#"+oldHeight;
		}
	}
}, 200);
</script>

C页面中的内容

C页面的唯一功能就是接收B页面通过href传进来的值并且传递给A页面,可到B页面传来的值可以通过一个定时器不停去查看location.href是否被改变,但是这样感觉效率很低,还有个方式就是在新的浏览器中通过onhashchange事件(IE8+,Chrome5.0+,Firefox3.6+,Safari5.0+,Opera10.6+)来监听href的改变。

<script type="text/javascript">
var oldHeight = 0;

setInterval(function(){
	var height = location.href.split("#")[1];
	if(height && oldHeight != height){
		oldHeight = height;
		if(window.parent.parent.getIfrData){
			window.parent.parent.getIfrData(oldHeight);
		}
	}
}, 200);
</script>

高度应用只是iframe跨域传值中最简单也是最常见应用,其实能扩展出很多其他的需求,之前在Yahoo的项目中就将iframe中的弹出框操作也传递到了外面,以保证样式的统一和页面的全遮盖。

最后举个“栗子”,演示请看http://www.honglei.net/demo/iframe_a.html

Centos 虚拟机网络的处理

公司大规模使用KVM,很多时候就是把Centos的虚拟机克隆后直接使用。直接克隆带来的问题就是网卡设置会发生变化,需要调整。一般会有一下几个问题。

网卡变成了eth-2和eth-3

其实这个并不影响使用,但是有些时候就是看着不爽;这个是可以调整的,方法如下

vim /etc/udev/rules.d/70-persistent-net.rules

里面可以看到所有网卡的mac和相关信息,直接删除上面的两块网卡配置,并且将下面的网卡设置中的name更换成eth-0和eth-1就可以;重启,再使用ifconfig查看,发现已经是eth-0和eth-1了

每次需要重新设置IP地址中的MAC

有时克隆后的虚拟机并不需要更改IP,就算需要更改IP也会有个讨厌的事情,就是同时需要修改设备的MAC地址,那个东西还超级难记住;
其实不用这么纠结,直接把设置文件中的MAC地址那项删除即可

vim /etc/sysconfig/network-scripts/ifcfg-eth0
删除 HWADDR="00:1E:0B:XX:XX:XX" 这行

这样以后更换虚拟机网卡就再也不用修改MAC地址

DNS设置

说起来这个不算虚拟机中的东西,不过也说说,很多时候可以ping通IP,但是无法ping通域名,那就要设置DNS了

vim /etc/resolv.conf
添加一下格式的内容
nameserver 8.8.8.8

局域网内可能很多请求是内部的,但是使用IP有些时候遇到服务器调整就需要都去修改,其实可以使用内部的DNS服务器来做服务器请求的统一管理。

服务器名称修改

虚拟机克隆以后换作其他用途,但是机器名还是原来的,好郁闷吧,这个也可以修改

vim /etc/sysconfig/network
修改 HOSTNAME= 后面的值即可
也可以用 hostname newname 即时修改机器名称(重启后无效)

然后重启就OK