Saber 酱的抱枕

Fly me to the moon

08/11
2016
学习

JavaScript中的变量提升

JavaScript有个叫“变量提升”的特性,意为:
在函数里声明的所有变量会被提升到函数顶部声明(但不涉及到赋值)。

示例:

var a=0;
!function(){
	alert(a);
	var a=1;
}()

在函数外声明了变量a=0,之后在函数里重新声明了a=1。
在这中间我们弹出a,它的值不是0,而是undefined。这就是变量提升导致的。发生变量提升之后,函数里声明的a被提升到函数顶部声明了(但这并不涉及到赋值),所以代码实际上相当于这样:

var a=0;
!function(){
	var a;
	alert(a);
	a=1;
}()

所以如果函数外已经声明了一个变量,那么就不要在函数内重复声明它,这样将会触发变量提前,可能会造成一些问题。

如果需要在函数内重复声明,那么将这些变量在函数顶部先声明但不赋值(就是写得和变量提升后的实际代码一样),可以让代码更直观。

其实这个概念是我昨天发布了搜索bilibili评论工具时,8q给我指出的。今天看书很巧的也看到了这个地方,弄清楚了。

JavaScript中的变量提升

08/9
2016
学习 软件

在bilibili评论区搜索某人评论的工具

此工具已失效!

saber pixiv

我用JavaScript写了一个小工具,在b站视频播放页面执行,可以在当前视频的所有评论里查找指定用户发出的评论。

举个例子:你(或是别人)在某视频下发了一条评论,但没记住楼层。现在,如果你想要在众多评论里找到自己(或其他某个人)发的评论,可以使用本工具。

本工具可以搜索完所有的楼层,但查找楼中楼时,本工具只能查找到每个楼中楼的前5条回复(所以对于楼中楼,可能会有遗漏)。

如果你有油猴扩展,可以到UserScript安装页面安装此用户脚本。

如果你没有油猴扩展,你可以手动执行代码。下面提供两种执行方式:

1.控制台执行以下代码,它会远程加载js文件来执行:

var newscript=document.createElement("script");
newscript.src="/f/bilibili_comment_search.js";
document.body.appendChild(newscript);

这种方法的话,由于我的js的url是http的,所以在B站的https页面里无法执行,可以在地址栏把b站这个页面的网址手动改成http的。

2.下载js文件,然后手动复制其代码到控制台执行。

代码执行之后,在视频上方会出现“查找评论”的文字:

点击它,输入想查找的用户的id(就是打开TA主页时网址里的数字)。之后,每当找到这个人发的一条评论,就会在控制台输出该评论的楼层信息。

注意要在控制台看哦~我们可以根据页数和楼层数提示去找到这条评论。

如果工具搜索完了所有评论,会弹出搜索到了几条结果。如果你想中途停止搜索,点击视频上方的提示文字即可。
Read More →

在bilibili评论区搜索某人评论的工具

08/6
2016
学习

JavaScript对日期排序

假设现在获得了一些格式化的时间/日期字符串,如何用JavaScript对其排序呢?

理想的办法就是用Date.parse()方法将这些字符串解析为时间,直接比较它们的毫秒数。示例如下:

function sortDate(sortby) {
    return function(object1, object2) {
        var value1 = Date.parse(object1);
        var value2 = Date.parse(object2);
    	if(value1>value2){
    		return (sortby==="desc")?-1:1;
    	}else if(value1<value2){
    		return (sortby==="desc")?1:-1;
    	}
    }
}
var a=["2017/4/20","2016/6/3","2016/7/1","2016/7/27","2017/8/4","2016/10/13","2016/12/27","2017/1/14","2017/2/3","2017/2/3","2017/2/3","2017/2/3","2017/2/3","2017/2/3","2017/2/3","2017/3/1","2017/3/1","2017/3/1","2017/3/1","2017/3/1","2017/3/1","2017/3/1","2017/3/23","2017/3/31","2017/5/19","2017/5/19","2017/6/2","2017/6/24","2017/6/24","2017/6/24","2017/9/1","2017/9/5","2017/12/12","2018/2/19","2018/9/26","2017/5/19","2017/3/9","2017/7/14","2017/5/19","2017/5/19"];
a.sort(sortDate("desc"));

结果如下:

上例定义了一个sortDate函数,我们在数组的sort方法里将它作为参数。如果不手动设置排序参数为desc,那么这个函数将始终按升序排序。

标准的时间/日期格式如下:

"2017/4/20 16:20:30"

当然,只用一部分,或者改变下连接符,也是可以解析的。
Read More →

JavaScript对日期排序

08/5
2016
学习

关于在阿里云备案的“空壳网站”被注销备案的问题

这蛋疼的玩意……

更蛋疼的是这网站的备案根本不是我去备的……

好了不扯废话了,这封邮件意思是这样的:

这个域名是通过阿里云备案的,因此这个域名必须使用阿里云旗下的服务器(这个是正常的)。

现在在阿里云的服务器上找不到有这个域名的内容,所以被判定为空壳网站,将要被注销备案。

其实网站是有内容的,只是没放在阿里云上。但管局只看你在阿里云上有没有内容,不管你是不是放在了其他地方。(所以说备案备的是主机,不是域名)

你问我这个域名为什么会这样,我可以回答无可奉告,但你又不高兴。其实这个域名是快速备案弄的。网站从来就没放在阿里云的服务器上(我们也没有阿里云的服务器),但是备案的人走的是阿里云。现在似乎是事情败露的感觉?

实际上要解决的话,不需要我们把整个网站都迁移到阿里云上面去。我们可以买一个最低配置的空间或服务器,然后只解析一个无关紧要的二级域名上去就行了,这样不会影响我们网站的正常运转。当然,解析的这个二级域名里还得放些页面,不能是一个空站。这样就可以通过它的检查了。

其实阿里云和其他大部分主机商有个区别。我们提交备案时管局会记录我们服务器的ip。在其他主机商那里,如果你换了一台服务器(即使还是他们家的服务器),但ip变了,就得做变更备案。阿里云则不然,只要你服务器是在阿里云旗下,ip变了也不用做变更备案(至于是不是阿里云会在后台自动做变更,我不知道)。这算是个方便的地方吧。

关于在阿里云备案的“空壳网站”被注销备案的问题

08/4
2016
学习

被百度云加速CDN缓存坑惨了的我在伤心过后决定控诉它

前天换掉了某网站上的两张图,但是在浏览器里看死活就刷新不过来。就算把这张图片删掉也还是能打开。

后来ping了一下域名,ip竟然不是我们服务器的ip。

我去百度云加速里查看解析记录,发现解析的是对的。

于是我就去问客服小哥,他们说ping到的ip是他们百度的节点ip。

我忽然间明白过来了,图片没改变是百度缓存导致的吧。

于是我去清除了下cdn缓存,果然好了。

百度云加速 cdn 缓存

这问题折腾了我一个小时,心好累。

被百度云加速CDN缓存坑惨了的我在伤心过后决定控诉它

07/31
2016
学习

获取WordPress文章的短链接

如果我们启用了WordPress的固定链接,那么每篇文章都会有一个短链接和一个固定链接。短链接是数字id,固定链接则是根据我们预设的格式生成的。

如本文有以下两个链接可以打开:

获取WordPress文章的短链接
http://www.saber.love/获取wordpress文章的短链接

由于短链接是不会变的,而固定链接却可以被修改,所以发布网址时,使用短链接更加可靠。

以前WordPress在编辑文章时有个获取短链接按钮,现在没有了。我照网上说的一些方法也没能让它显示出来。不过仍然有两个办法可以看到短链接:

1.编辑文章时点击预览,在预览页面的url里包含有文章id。发布过的文章、没有发布的文章,都可以这么看。
2.在文章的前台页面里,也保存有短链接。我们可以执行如下代码获取它:

document.querySelectorAll("link[rel=shortlink]")[0].href

获取WordPress文章的短链接

07/26
2016
学习

原生Ajax的简单实例

因为JavaScript水平太渣,以前我都是用JQuery来做ajax。现在看了些资料,感觉原生的写法也不难,而且兼容性也已经不错了,所以跟着练一练。

同步的ajax请求:

var xhr=new XMLHttpRequest();
xhr.open("get","http://saber.我爱你/demo/checknew.php",false);
xhr.send(null);
if (xhr.status===200) {
	alert(xhr.responseText);
}else{
	alert("发生了异常,状态码为"+xhr.status+","+xhr.statusText);
}

返回的数据里有如下属性:
responseText:作为响应主体被返回的文本。
responseXML:如果响应的内容类型是"text/xml"或"application/xml",这个属性中将保存包含着响应数据的XML DOM 文档。
status:响应的HTTP 状态。
statusText:HTTP 状态的说明。


异步的ajax请求:

var xhr=new XMLHttpRequest();
xhr.onreadystatechange=function(){
	if (xhr.readyState===4) {
		if (xhr.status===200) {
			alert(xhr.responseText);
		}else{
			alert("发生了异常,状态码为"+xhr.status+","+xhr.statusText);
		}
	}
}
xhr.open("get","http://saber.我爱你/demo/checknew.php",true);
xhr.send(null);

检测状态的部分也可以这样写:

xhr.onload=function (argument) {
	if (this.status == 200) {
		//……
    }
}

异步请求除了在xhr.open里将最后的参数设置为true之外,在接收数据时也和同步请求不同。异步请求通过检查xhr对象的readyState属性来判断请求处在哪个阶段。当readyState为4时,表示接收到了数据,并且数据可用。

我们通过onreadystatechange事件来检测readyState的值,当值为4时即可对数据进行处理。

另外,在接收到响应之前还可以调用abort()方法来取消异步请求。即xhr.abort(); 。

原生Ajax的简单实例

07/21
2016
学习

php截取中文不乱码的代码

php中最常用的截取文字的函数是substr(),但是在该函数中,中文占用2个或3个长度,所以可能把汉字截断,产生乱码。

有一个办法是使用mb_substr()来截取文字。这样确实可以,因为mb_substr()把所有文字都当做一个长度,所以截取中文时是整个字截取的,不会乱码。但mb_substr()的长度计算方法和substr()不同,有时候反而不能用它。经过一番苦搜,我找到了用php的ord()函数来截取文字的办法。

这种方法的字数计算方法和substr()一致,但不会导致汉字被截断.如果指定的长度会截断汉字,它会把因截断而产生的残缺汉字扔掉(以最后截取出来的长度有可能会比指定的长度少一两位。)。

另外它的参数也只有两个,一个是字符串,一个是截取长度。没错,它不能指定起始位置。

GBK版本:

function gb2312_substr($str, $limit) {
    $restr ='';
    for($i=0;$i< $limit-3;$i++) {
        $restr .= ord($str[$i])>127 ? $str[$i].$str[++$i] : $str[$i];
    }
    return $restr;
}

UTF-8版本:

function utf8_substr($str, $limit) {
    $restr = '';
    for($i=0;$i< $limit-3;$i++) {
        $restr .= ord($str[$i])>127 ? $str[$i].$str[++$i].$str[++$i] : $str[$i];
    }
    return $restr;
}

php截取中文不乱码的代码

07/18
2016
学习

php获取url的状态码

function http_status($url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, 1);
    curl_setopt($ch, CURLOPT_NOBODY, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_TIMEOUT, 5);
    curl_exec($ch);
    $status = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    return $status;
}

可以用这个函数来获取url请求的状态码,判断404很方便→_→

不过如果测试p站图片url的话,还得加上refer信息来绕过防盗链。

一个下载器搞得我找了好多php的东西,心好累。

php获取url的状态码

07/15
2016
学习

关于PHP操作文件时最长文件名的研究

先吃我大鼻孔

今天我在改进pixiv下载器,想把tag信息保存到文件名里。前两天我研究了“windows中文件名最大长度的问题”,也是为这个做准备。我很快把获取tag的代码写好了,也在php里限制了文件名最大长度。但是做完之后感觉有点不对劲。怎么不对劲呢?下载图片的失败几率比以前大大提高了。错误都是:

Warning:fopen() Invalid argument

那么到底文件名哪里不对呢?这问题折腾了我五六个小时,我下班都没回去,坐在办公室里还在研究这个问题。天见可怜,我终于还是找到了问题的真相。

问题还是出在长度上。

windows计算文件名(包括路径)都是按【字数】算的,也就是说,不管你是中英混合还是怎么的,都能写满256个字。

我以为用php去创建文件也可以这样,于是我在php里用mb_strlen()函数去计算字数,这个函数也是把一个文字当做一个长度算。结果我这样做是错的,php虽然也会限制文件名和路径长度之和不能超过256个字符,但它真的只是字符长度,不是字数。所以php里操作文件时,涉及到文件名长度,要使用strlen()函数。

strlen()的计算方法是,英文占一个字符,而中文字符在gbk编码中算两个字符,在utf8编码中算三个字符。还好我使用的gbk编码,否则能用的字数要更少了。

下面这个路径在php的gbk编码中算做256长度(字节?):

F:\wamp\www\t/pixivimg/专辑1422_ 【一无所有的“死亡回归”!】Re 从零开始的异世界生活特辑 /56938050_p0_tag-ナツキスバル,Re ゼロから始める異世界生活,スバル,菜月昴,ゼロから始める異世界生活,リゼロ,リゼロ500users入り,Re ゼロから始める異世界00usersxxxxxxx入り.jpg

当然,用windows的计算方式,刚到170个长度。

好吧……为了在有限的长度里多给tag腾腾地方,我把文件名里很多东西都去掉了。标题啊,日期啊什么的都扔了,只留下图片id和tag。现在的文件名是这样的:

19566474_p0-よんでますよ、アザゼルさん。,十点じゃ足りません!,ふつくしい,なにこれ綺麗,サラマンダーwwwwww,一体だけ浮いてるw,まんまですよ、マンダはん,アザゼルさん1000users入り,キャプショ.jpg

这个长度已经接近极限了。心好累,感觉不会再爱了。

关于PHP操作文件时最长文件名的研究