前两天一个朋友说他电脑上淘宝无法登陆,登陆页面上所有图片都没有,而且整个页面都是乱的,开始以为是不是去了钓鱼网站,后来通过远程确认网址是正确的,通过清除浏览器缓存等一些列操作,问题依旧。后来直接访问支付宝时提示网站数字证书过期无效,心想支付宝这么大的站应该不会犯这样错误吧,在本人机器上登录又没有提示这样错误,在网上查询了一下,如果系统时间不对可能会造成这样错误,遂看看他机器的系统时间,一看是2002年的,果然是时间有问题,把时间修改正确后,再次访问支付宝问题,没有提示整数出错了,通过淘宝登陆也是好的。查看了一下淘宝登陆页面,发现里面用到的css、js和图片资源都是https的,由于时间问题导致证书无效后,这些资源都无法加载,所以页面只显示基本乱七八糟的。
mac下通过软件parallels desktop虚拟安装了一个win xp。parallels desktop就是和vmware,virtualbox类似的虚拟机软件,在mac下parallels desktop功能超强大。在虚拟机中通过共享的方式很容易访问到mac下的硬盘,但我遇到的问题是需要把mac下的某个程序文件夹复制到win xp下,而且程序修改都是在mac下进行的,最开始的做法是修改程序后去win下面手动拷贝,程序还是在增加修改中,所以这真不是一个好办法。后来发现在finder中也可以看到win xp的硬盘,当然也可以访问,方法是打开finder后,使用command+向上方向键一直到最顶层目录就可以看到。进一步发现win xp的硬盘是挂载在/private/tmp目录下的,通过命令mount可以看到类型下面的信息:
vfstool@prlufs0 on /private/tmp/96967/C (prlufs, nodev, noexec, nosuid, synchronous, mounted by yangyz)
上述数字96967是不固定,重启虚拟机后就变化了,那到底代表是什么呢?观察任务管理器,发现原来它就是进程“prl_vm_app”的pid号。知道了其中的奥秘,那事情就好办了,写一个shell脚本,使用rsync来让它同步文件夹的内容,这样就可以做到自动处理了。简单代码如下:
#/bin/bash
pid=$(ps aux | grep prl_vm_app | grep -v "grep" | awk -F" " '{print $2}')
src=/Users/xxxx/macdir/
dest=/tmp/${pid}/C/windir/
while true
do
if [ -d "$dest" ]
then
rsync -vzrtopg --progress --exclude-from=exclude.list $src $dest
fi
sleep 3
done
hypertranslate是firefox下一个翻译的扩展,可以自定义翻译的目标语言,支持划词翻译,后台数据是通过google 翻译api接口,因此可以自动识别源语言并翻译到目标语言,个人觉得很好用的一个扩展。扩展的安装地址:https://addons.mozilla.org/zh-tw/firefox/addon/hypertranslate/。
另外该扩展还提供chrome、safari,但我在mac下chrome下安装后无法使用。
firefox下有用的扩展很多,但是某些有用的扩展会自动添加到右键菜单中,使得右键菜单变得很长,可能突然在已有的右键菜单增加了一个新的项目会让人感到很不习惯,但firefox默认似乎没有地方让用户自己定义右键菜单的内容。那要想去掉怎么办呢?扩展的事就让扩展去解决吧。有一款名为Menu Editor的扩展就能解决这个问题,扩展的安装地址为:https://addons.mozilla.org/en-us/firefox/addon/menu-editor/
目前很多网站的页面上在右下角都提供了一个“回到顶部”的按钮。今天无事决定自己写一个,代码其实很简单,经过几次修改后,效果还算满意。重要的是全部使用js来实现,不需要在html、css中增加任何内容,甚至都不需要图片,只要引用js即可。而且全面兼容IE6。由于考虑兼容性问题,如何获取滚动条的高度和按钮停留在右下角是难点。这两个问题可以参考:js如何获取滚动条的高度,兼容各个浏览器的右下角提示框代码。
代码如下:
(function() {
var btnId = '__gotop';
var isIE = !!window.ActiveXObject && /msie (\d)/i.test(navigator.userAgent) ? RegExp['$1'] : false;
function $() {
return document.getElementById(arguments[0]);
}
function getScrollTop() {
return ('pageYOffset' in window) ? window.pageYOffset
: document.compatMode === "BackCompat"
&& document.body.scrollTop
|| document.documentElement.scrollTop ;
}
function bindEvent(event, func) {
if (window.addEventListener) {
window.addEventListener(event, func, false);
} else if (window.attachEvent) {
window.attachEvent('on' + event, func);
}
}
bindEvent('load',
function() {
var css = 'background-color:#999;width:50px;height:50px;position:fixed;right:100px;bottom:30px;border-radius:10px;cursor:pointer;display:none;';
if (isIE && isIE < 7) {
css += '_position:absolute;_top:expression(eval(document.documentElement.scrollTop+document.documentElement.clientHeight-30-this.offsetHeight-(parseInt(this.currentStyle.marginTop,10)||0)-(parseInt(this.currentStyle.marginBottom,10)||0)))';
var style = document.createStyleSheet();
style.cssText = '*html{background-image:url(about:blank);background-attachment:fixed;}';
}
var html = '<div style="height: 0;width: 0;border:14px solid #999999;border-top: 0 none;border-bottom:14px solid #fff;position: relative;margin:12px 0 0 11px;"><div style="width:8px;height:7px;position:absolute;top:14px;left:-4px;background-color:#fff;overflow: hidden;"></div></div>';
var el = document.createElement('DIV');
el.id = btnId;
el.style.cssText = css;
el.innerHTML = html;
document.body.appendChild(el);
el.onclick = function() {
(function() {
var top = getScrollTop();
if (top > 0) {
window.scrollTo(0, top / 1.2)
setTimeout(arguments.callee, 10);
}
})();
};
el.onmouseover = function() {
$(btnId).firstChild.style.borderBottom = '14px solid #ddd';
$(btnId).firstChild.firstChild.style.backgroundColor = '#ddd';
};
el.onmouseout = function() {
$(btnId).firstChild.style.borderBottom = '14px solid #fff';
$(btnId).firstChild.firstChild.style.backgroundColor = '#fff';
};
}
);
bindEvent('scroll',
function() {
var top = getScrollTop(), display = 'none';
if (top > 0) {
display = 'block';
}
if ($(btnId)) $(btnId).style.display = display;
});
})();
效果见本blog。
方向箭头大部分都是使用图片来实现的,其实还有一种选择,就是使用纯css来实现。原理是借助dom对象的border属性,border属性可以细分为border-left、border-top、border-right和border-bottom。先观察下述css代码和对应的显示效果。
#box1 {
height: 0;
width: 0;
border-left: 50px solid gray;
border-right: 50px solid yellow;
border-top: 50px solid green;
border-bottom: 50px solid blue;
}
#box2 {
height: 0;
width: 0;
border-left: 50px solid gray;
border-right: 50px solid yellow;
border-top: 50px solid green;
border-bottom: 0 none;
}
#box3 {
height: 0;
width: 0;
border-left: 50px solid gray;
border-right: 0 none;
border-top: 50px solid green;
border-bottom: 50px solid blue;
}
效果图如下:
通过观察box1,可以看到某一个细分border都是相对于中心点的一个三角;box2和box3则可以看到,如果当设置为0时,就会去掉从中心到对应边的部分。假设需要获取一个向下的方向键,那么可以在box2上进行改造了,只需要去掉去掉左右的两个小三角即可。如何去掉呢?很简单,只需要设置他们的颜色和背景颜色一致即可。例如:
#box2_1 {
height: 0;
width: 0;
border-left: 50px solid #ffffff;
border-right: 50px solid #ffffff;
border-top: 50px solid green;
border-bottom: 0 none;
}
或
#box2_1 {
height: 0;
width: 0;
border:50px solid #ffffff;
border-top: 50px solid green;
border-bottom: 0 none;
}
可以参考上面实现来打造出另外几个方向箭头。颜色可以根据实际情况来设定。
由于市面上浏览器的种类众多,但是浏览器没有一个通用的方法来获取该值,想做到每个浏览器都兼容还是要下一些功夫的。
目前主流浏览器除IE外对浏览器标准支持都比较好,例如chrome、firefox以及safari等。对应后者,可以通过window对象的pageYOffset属性来取到当前滚动条到页面顶部的高度。对于万恶的IE来说就比较麻烦一点,它依赖当前文档类型。文档类型分为Standards Mode和Quirks Mode,页面声明了DOCTYPE时为Standards Mode,反之为Quirks Mode。可以使用document.compatMode来获取,该方法也同时支持其他浏览器,其返回值为BackCompat或CSS1Compat,含义如下:
BackCompat Standards-compliant mode is not switched on. (Quirks Mode)
CSS1Compat Standards-compliant mode is switched on. (Standards Mode)
由于IE对盒模型的渲染跟文档类型有很大关系,所以获取滚动条高度的方式也是不一样的。当文档类型为Standards Mode,获取方式为:document.documentElement.scrollTop,而Quirks Mode时则为:document.body.scrollTop。
理解上面的所提到的差异后,用代码实现就很容易了,具体实现的代码如下:
function getScrollTop1() {
if ('pageYOffset' in window) {
return window.pageYOffset;
} else if (document.compatMode === "BackCompat") {
return document.body.scrollTop;
} else {
return document.documentElement.scrollTop;
}
}
甚至可以修改上述代码,使用一行代码搞定,但是可读性没有上面好,代码如下:
function getScrollTop() {
return !('pageYOffset' in window)
? (document.compatMode === "BackCompat")
? document.body.scrollTop
: document.documentElement.scrollTop
: window.pageYOffset;
}
或
function getScrollTop() {
return ('pageYOffset' in window) ? window.pageYOffset
: document.compatMode === "BackCompat"
&& document.body.scrollTop
|| document.documentElement.scrollTop ;
}
另外除了上述document.compatMode的方式来获取文档类型外,还可以使用 document.defaultView来获取。在IE 9以下的Quirks Mode中document不支持defaultView属性。参考地址:https://developer.mozilla.org/en-US/docs/DOM/document.defaultView。
访问网站提示500错误,通过查看日志,获得错误信息为:
2012/12/06 16:10:52 [alert] 11679#0: *9189 1024
worker_connections are not enough while connecting to upstream,
client: 127.0.0.1, server: xxx.netingcn.com,
request: "GET / HTTP/1.0", upstream: "http://127.0.0.1:80/", host: "xxx.netingcn.com"
对于上述错误网上很多人提到,大部分情况是在生产环境中由于并发太多造成的。解决办法就是修改配置文件中的worker_connections值,将其调大。但是今天在本机的nginx中配置一个proxy,完全没有外界的访问的情况也提示上述错误,试着修改worker_connections也没有解决问题。proxy配置大致如下:
server {
listen 80;
server_name yyy.netingcn.com;
location / {
root /var/www/netingcn.com;
index index.html index.php;
}
}
server {
listen 80;
server_name xxx.netingcn.com;
location / {
proxy_pass http://yyy.netingcn.com/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
}
}
原本的目的是想把所有请求xxx.netingcn.com代理到yyy.netingcn.com,也许你会纳闷,干嘛要这么麻烦,直接在第一个的server_name中添加xxx.netingcn.com不就完事。这里只是一个举例,由于正式环境下有特殊情况,不能那么配置,所有才会想到用proxy的方式。
上述配置造成的500错误可以肯定排除是worker_connections太小的原因,仔细配置,发现“proxy_set_header Host $http_host;”这个才是罪魁祸首,因为它造成死循环了,当请求xxx时,由于proxy到yyy,本来nginx是交给server yyy,来处理的,但是header里面的host还是xxx,nginx根据配置里面的server_name,找到 xxx,因此就显示了死循环,也就会报前面提到的那个错了。问题已经定位到了,解决就很简单,直接去掉proxy_set_header Host $http_host;这行配置就行了。
最近升级php memcached扩展到2.1.0,由于依赖libmemcached库,先前安装的版本是1.0.2,编译时候出错,需要更高版本的libmemcached,所以重新下载最新版本的libmemcached编译安装。不幸的时编译libmemcached 1.0.14时候保存,大致错误信息为:
libmemcached/auto.cc: In function 'memcached_return_t text_incr_decr(memcached_server_st*, bool, const char*, size_t, uint64_t, bool)':
libmemcached/auto.cc:73: error: expected `)' before 'PRIu64'
In file included from ./libmemcached/common.h:72,
from ./libmemcached/csl/common.h:40,
from libmemcached/csl/context.cc:38:
google查询了一下,原因是GCC的版本低了,所以只好升级GCC了,好在有yum,一条命令就搞定,命令如下:
yum install gcc44 gcc44-c++ libstdc++44-devel
把下面内容加入到/etc/bashrc中
export CC=/usr/bin/gcc44
export CXX=/usr/bin/g++44
退出终端然后重新登陆,编译、安装都通过了,同时也顺利升级memcached扩展。
今天遇到一个问题,调用对方接口,按照接口说明,返回为数字0,1,2等等,其中0标示成功,其他表示不同的错误代码。程序通过 if ($ret == 0) 进行判断,开始程序是好的,今天出现问题了,由于对方接口修改,直接返回字母字符串作为错误信息提示,然后我这边就悲剧了,上述判断永远都为TRUE。
原因在于php是弱类型语言,所以可以对两个不同类型的变量进行比较操作,但最终进行比较前,php会把某一方转换称另一方一样的类型,这点很重要。如果是字符串和数字进行比较,那么php会把字符串强制转换称数字,对于纯字母的字符串,那么转换后就是0了,所以if ($ret == 0) 成了。
附PHP官方介绍:http://php.net/manual/zh/language.operators.comparison.php