您正在查看: 2014年

HTML5 Notification API

与 WebkitNotification 的区别

过去,我们使用 window.webkitNotification 创建通知,但正如它的名字一样,这是个 Webkit 的专属接口,是在 HTML5 Notification 出来前的临时解决方案,在最新版 Chrome 中已经停用。

如何使用 HTML5 Notification API

根据 W3C 标准,创建一个 Notification 的正确方式是新建一个 Notification 对象,然后可以绑定这个对象的事件。不过在这之前,你需要用 Notification.requestPermission(callback) 方法请求创建通知的权限。

Notification 对象

创建一个 Notification 对象十分简单,只需要运行如下 JavaScript

var notification = new Notification(title, options)

其中 title 为通知的标题,options (可选) 为通知的参数,是一个 JavaScript 对象,对象可以包含如下属性:

dir: 显示顺序;可以使用 auto (自动)、ltr (从左到右)、trl (从右到左)
lang: 通知的语言;参见:RFC 5646: BCP 47 语言标识
body: 通知的正文
tag: 有点类似于 ID 的标识符
icon: 通知的图标

Notification 对象还有如下的静态属性:

Notification.permission
(只读) 用来查看当前网站是否有发送通知的权限

静态方法:

Notification.requestPermission
用于请求发送通知的权限,可以使用一个回调函数作为参数。在用户点击允许/拒绝时会触发回调函数

当你新建了 Notification 对象后,可以使用以下实例方法:

notificationObject.close()
关闭这条通知

notificationObject.addEventListener()
绑定事件监听器,这个不多说

notificationObject.removeEventListener()
跟上一个相反

Notification 对象后具有如下的事件:

notificationObject.onclick
当用户点击通知条时触发

notificationObject.onshow
当通知条显示后触发

notificationObject.onerror
当通知出现错误时触发(这个真没用过)

notificationObject.onclose
通知被关闭时触发

多用 MIN() MAX() 吧……

获取用户最后一次发帖的时间,可以用 MAX(timestamp) 做,也可以用 ORDER BY 做。

SELECT MAX(timestamp) FROM pre_forum_thread WHERE /* ... */

SELECT timestamp FROM pre_forum_thread WHERE /* ... */ ORDER BY timestamp LIMIT 0,1

结果使用 ORDER BY 的方法居然触发了 filesort QAQ~
好吧,以后坚决用 MAX() 和 MIN() 了……

解决 μTorrent 导致的磁盘占用 100% 问题

μtorrent 有个非常坑爹的问题,默认设置下,经常导致磁盘占用 100%……
任务管理器中提示 System 占用磁盘,甚至还害我重装了系统依然没办法解决。
最后使用监控软件才找到原来在不停读写 BT 下载目录文件……这才找到元凶……

μTorrent 默认情况下居然为了减少内存占用减少甚至关闭磁盘缓存……
导致出现了大量的磁盘 I/O 请求……尼玛这个年代还有人缺那几十几百M内存?都不够我开个 Chrome 的……
按下面配置修改后,就再也没有卡过 100% 了
QQ图片20140509223600.jpg

Nginx 简单防盗链规则

直接粘代码吧:

location ~* \.(gif|jpg|swf|flv|mp3|mp4|zip|rar)$ {
    valid_referers none blocked www.kookxiang.com kookxiang.com ikk.me ikk.me space.bilibili.tv;   #picture for http://space.bilibili.tv/648581
    if ($invalid_referer) {
        return 403;
    }
}

加到对应 vhost 的 Server 段即可。
上面的域名自己换就 ok 了

屌爆了的邮件转发服务 - Bouncr

现在互联网根本离不开电子邮件:注册需要电子邮件,密保要用电子邮件……甚至于每个网站都想要知道你的电子邮件地址。
但是,当你畅游互联网一段时间后,你会发现邮箱里多了一大堆垃圾邮件
其中最令人恼火的是你根本不知道是谁把你的电子邮件地址卖了的。
今天,要为大家推荐一个很棒很棒的邮件转发服务——Bouncr!

使用方法非常简单,首先打开 Bouncr:http://boun.cr
然后输入你的电子邮件地址,点击 Go 就可以得到你的 @boun.cr 转发地址。
以后你上网的时候就可以使用这个转发地址来当你的电子邮件地址来用了。
如果有邮件发到你的 @boun.cr 邮箱,它会被自动转发到你的真实邮箱。

如果你发现某个 @boun.cr 邮箱有很多垃圾邮件,你可以直接打开当初注册 boun.cr 后发来的邮件,点击 Manage 链接,可以直接 disable 掉这个邮箱。之后发往这个邮箱的邮件,就丝毫不会打扰你啦~
而且一个邮箱好像可以绑定多个 boun.cr 邮箱,你可以给每个网站设置不同的转发邮箱,这样你就知道到底是谁把你卖了(笑

让 Discuz 支持 MariaDB

昨晚把博客和论坛搬回国内了;博客在搬的过程中倒还挺轻松,只是 Discuz 搬迁后出现水土不服,提示

Illegal mix of collations (gbk chinese ci,IMPLICIT) and (latin1_swedish_ci,COERCIBLE) for operation '='

搜索后大概意思是说数据库编码不对。
我就郁闷了,数据库是 GBK 的,字段是 GBK 的,程序也是 GBK 的,怎么会编码有问题呢?
绕过计划任务进入论坛,发现论坛中文全部乱码了。
难道是我导入数据的时候有问题?于是乎我又重新用 GB2312 导出一份,上传到服务器,依然不行。
反反复复折腾一个小时之后,一个偶然的机会下发现 Discuz 下数据库被设置为 lantin 编码,这和 phpmyadmin 看到的不一样啊!
然后又研究了许久 Discuz 的数据库类,明明有设置为 GBK 的,难道没设置成功?
在程序中加入 DB::query() 设置编码,发现居然可以了,这是什么道理??表示不服
难道用 mysql_query() 就不行么?可是 DB::query() 又是调用 mysql_query() 的啊
偶然调节代码顺序的时候,发现移动到 if($this->version() > '4.1') 外侧竟然执行成功了
尼玛原来你才是罪魁祸首
可是这句话有问题么?输出下

10.0.9-MariaDB

尼玛我瞬间就明白了,这是一个字符串,“4.1”也是一个字符串,字符串比较是逐一比较各字符,先判断 1 < 4,然后得出 10.0.9-MariaDB < 4.1
我 QNMLGB,害我倒腾两个小时……

解决办法:
修改 version 方法,return '9.9.9';

让 Discuz! 帖子列表支持倒序排序

Discuz! 虽然能够在后台修改帖子的排序方式,但却不能选择是倒序还是顺序排序。
为解决这个问题,可采用以下修改办法:
修改文件 source/module/forum/forum_forumdisplay.php,找到 457 行:

$_GET['ascdesc'] = isset($_G['cache']['forums'][$_G['fid']]['ascdesc']) ? $_G['cache']['forums'][$_G['fid']]['ascdesc'] : 'DESC';

在下方加入:

http:// Modified by kookxiang @ 2014-4-8 13:05:07
if($_GET['forceasc']) $_GET['ascdesc'] = 'ASC';
if($_GET['forcedesc']) $_GET['ascdesc'] = 'DESC';
http:// Ending of modification

这样便能通过 URL 参数 forceasc 和 forcedesc 控制排序了

离开 WiFi 范围自动禁用 WiFi

学生党表示宿舍长期开着WiFi,出去上课的时候总是不记得关。
本着能省一点是一点的精神,希望离开WiFi范围的时候能自动关掉,于是自己动手写了个。
程序本身不占用任何资源,没有后台进程。自动注册一个网络状态监听器,当WiFi断开一段时间之后关闭WiFi。
值得注意的是,由于 Android 4.0 以上版本的限制,要注册监听器必须至少启动过一次程序,所以装好后需要手动点一下图标
启动后程序自动隐藏程序图标(因为你点进去也没用 →_→)
之后可能会考虑加个连接充电器的时候自动扫描WiFi,放在无线充电板上爽歪歪(笑
下载在这里:KK Auto Wifi.apk
PS:原创作品,请勿转载,谢谢

小白向的系统重装教程

文章随时可能更新,转载时请注意保留本人署名和本文链接,谢谢!

说明

很多新手在重装系统的时候都要找所谓的“高手”来帮忙重装系统,在大家眼中重装系统好像是件很高科技的事,其实重装系统很简单,从 Windows 的最初版本开始微软就在不停的改进系统安装的方法,每一代的系统比起上一代来说都更容易安装 / 使用。所以不用担心重装系统会很麻烦,你要做的就是把你电脑里你认为重要的东西、不想删掉的东西,复制到其他地方避免丢失,然后就可以跟着教程重装系统了。
在这个教程中,我会用尽可能容易理解的方式来教大家怎样重新安装操作系统。
我会尽可能把应该考虑的细节写下来,虽然可能有点啰嗦,不过很多东西只要大概了解下就好。

为什么要自己重装系统?

电脑用了一段时间之后,常常会因为各种问题而恼火:功能不正常、操作卡顿、蓝屏死机、中了木马病毒……这些问题大多都能通过重装系统得到解决。
学会怎样重装系统之后,当你电脑崩溃的时候就不再需要到处求人了。而且现在电脑 90% 的问题都能通过重装系统解决,如果重装解决不了,那便很可能需要更换电脑中的零部件了。
自己重装的系统可以放心,这样的系统完整又干净,按教程说的装好系统也需要担心病毒木马。
另外还可以在女朋友 / 男朋友面前炫耀一把

决定好你要安装什么版本的系统

先想好你要装什么系统,不然之后后悔是件麻烦的事。
建议的系统有:

Windows 7 (推荐,发布时间较旧)
Windows 8 (前两年发布的系统,采用了很多新技术,速度快,有的软件可能不能用)
Windows 8.1 (是 Windows 8 的更新版本,更适合用鼠标操作)

决定之后你需要下载安装镜像,一个比较靠谱的下载地址是:http://msdn.itellyou.cn
例如需要安装 Windows 7,则在左边依次点击 操作系统 -> Windows 7 -> 简体中文
如果你有正版的序列号,可以选择序列号对应的系统;
如果你不是正版用户,那么就选择一个功能全一点的。

个人建议的选择方案:

Windows 7 Ultimate with Service Pack 1(旗舰版,带SP1,可以少打很多补丁)
Windows 8 (基本版和专业版都有,安装时建议安装专业版)
Windows 8.1 (同上,请下载 Multiple Edition 合盘版)

你会发现同样的系统有 x86(32位)和 x64(64位)两个版本,怎么选择呢?
我的建议是:如果你的电脑是好几年前的,或者内存小于 2GB,那么可以考虑 x86,否则请选择 x64.
点开“详细信息”之后你就能看到一个 ed2k:http:// 开头的地址,把他复制到你的迅雷就可以开始下载了。

下载好之后,我们就能用这个安装镜像开始安装系统了。

- 阅读剩余部分 -

Discuz! 3.0 产品中的CSRF漏洞

漏洞利用:

[img]admin.php?frame=no&action=members&operation=clean&submit=1&uidarray=1&confirmed=yes[/img] (可删除UID1用户)


有一定 discuz 开发基础的人一定对 submitcheck() 这个函数不陌生吧

没错,这个就是 Discuz! 对 CSRF 攻击做的防御函数

这个函数会判断请求中 formhash 的值,避免伪造的访问

今天在编写某款插件的时候偶然将带有 FORMHASH 字样的代码(即“FORMHASH”字符串)扔进了 Chrome 的 console,结果意外打开了插件的提示框,代码本来是这样的:

/* 前略 */
if(submitcheck('submit', true)){
    http:// ........
} else {
    http:// .........
}

按理说 submitcheck 是会判断formhash的,而我给的formhash肯定是错误的

然后我又将 formhash 改为123456,结果依然过了formhash的判断

郁闷了,然后我就去看了 submitcheck 这货的实现方法

submitcheck -> helper_form::submitcheck

找到 source/class/helper/helper_form.php,节选部分代码:

public static function submitcheck($var, $allowget = 0, $seccodecheck = 0, $secqaacheck = 0) {
        if(!getgpc($var)) {
            return FALSE;
        } else {
            global $_G;
            if($allowget || ($_SERVER['REQUEST_METHOD'] == 'POST' /* 此处略去 */)) {
                if(checkperm('seccode')) {

你妹!!!!!!!

$allowget 就不管后面了???

formhash 拿去喂腾讯了???

无语,然后搜下,submitcheck($string, 1) 这种用法 discuz 自己也用……

剩下的自己YY吧

  1. 1
  2. 2
  3. 3