一个js的怪异问题排查经过

最近不知道怎么了,老是碰到各种怪异问题,查起来费半天劲,最后查出来其实不是代码的问题,囧...

今天又碰到个js的怪异问题,特地记录以免以后再走弯路。

页面的代码如下:


	

这段代码是Discuz!7.0的悬浮广告和对联广告的代码。
页面输出后的源码为:

在chrome的开发者工具下看到有如下的报错:

Uncaught ReferenceError: theFloaters is not defined

theFloaters这个是在include/js/floatadv.js文件里定义的,前面明明已经引入了此文件,怎么出现未定义这样的报错呢?
跟模板文件的代码比对后,发现在引入floatadv.js文件的js后面多了一段style样式代码,如下:

style="display: none; visibility: hidden; "

查过代码发现没有地方会有增加这段style的地方,而且在chrome开发者工具的script标签下居然也找不到floatadv.js这个文件,但是网络标签下明明加载了这个文件。

查了半天,突然想起来会不会是广告过滤扩展搞的鬼,因为这个js的文件名里带有ad。
禁用掉ABP扩展后再试,悬浮和对联广告全出来了,也没有了之前的报错。
内牛满面啊,扩展你丫太强大了也!!

十分之一的中国

网易2010春运策划:十分之一的中国。

1235条空中航线
8万公里铁路
373万公里公路
以及无数的江河
如密不透风的毛细血管
正年复一年地目睹一场空前的迁徙

1亿5千万中国人离开家
去城市,去大城市,去首都
为了更好的工作、更好的学校和医院
现在他们正在回家的路上

当一列火车远远驶来

请致敬
向十分之一的漂泊中国
向生活在别处的中国人

fsockopen返回null的怪异问题排查

今天测试过程中发现fsockopen请求有问题,代码里进行了断点记录,具体代码如下:

if(function_exists('fsockopen')) {
	$fp = @fsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout);
        file_put_contents('d.log', var_export($fp)); // 断点记录
}

执行后,找到d.log文件,内容如下:

null

查了PHP手册里fsockopen函数的说明,如果失败应该是返回false。
呃,居然返回了null,十分怪异。网上搜索了下相关问题,没找到具体原因,但是有发现类似的问题。

没办法,本地重新写了个脚本test.php,具体代码(忽略部分代码):

$host = 'api.discuz.qq.com';

$port = 80;

$errno = 0;
$errstr = '';
$timeout = 30;

$fp = fsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout);
var_dump($fp);

执行这个脚本,输出结果为:

resource(21) of type (stream)

囧,居然成功了。
好吧,两个的区别是一个是用文件记录的,另一个是直接输出的。

将test.php文件的代码改为如下:

$host = 'api.discuz.qq.com';

$port = 80;

$errno = 0;
$errstr = '';
$timeout = 30;

$fp = fsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout);
var_dump($fp);
file_put_contents('d.log', var_export($fp, TRUE));

执行后,页面直接输出还是

resource(21) of type (stream)

但是文件里记录的内容却是:

null

好吧,问题就处在var_dump和var_export这两个函数上。
在PHP手册上关于var_export函数的说明里找到下面一句话:

Variables of type resource couldn't be exported by this function.

资源类型的变量不能使用这个函数输出。

var_export() differs from print_r() for variables that are resources, with print_r() being more useful if you are using the function for debugging purposes.

如果是调试目的的话,print_r更为有用。

回到test.php文件,修改为下面的代码:

$host = 'api.discuz.qq.com';

$port = 80;

$errno = 0;
$errstr = '';
$timeout = 30;

$fp = fsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout);
var_dump($fp);
echo "\n";
var_dump(var_export($fp, TRUE));
echo "\n";
print_r($fp);

执行后,页面的输出为:

resource(14) of type (stream) 
string(4) "NULL" 
Resource id #14

0116更新:
今天又碰到返回为null的情况了。。
接口里不好判断,单独写了个脚本模拟了下,发现fsockopen返回如下信息:

unable to connect to 192.168.0.180:80 (No route to host)

问了下系统的同事,说是这台服务器和要请求的服务器不在一个机房,没法用内网IP。
改成用host请求就可以了。