Sublime使用笔记以及插件推荐

自从换了 Linux 就摆脱了笨重的 VS 这个强大的开发工具,自动提示,自动纠错.... VS 为我提供了太多功能,已经把我宠坏了...以至于普通的编辑器我都无法习惯... 这样可不是什么好习惯,不过 Sublime Text 2 是个很好的编辑器,特别是它的插件特别 丰富提供了很多实用的功能.于是在 Linux 下前端开发基本就是实用它了. 虽说是收费软件,但是个人用户可以无限期的免费试用,只不过经常提示购买罢了...

# 基础配置

个人喜欢亮色系的输入环境于是换成 Dawn 主题,并且修改了字体和大小

{
  "color_scheme": "Packages/Color Scheme - Default/Dawn.tmTheme",
  "font_face": "Deja Vu Sans Mono",
  "font_size": 11.5,
  "ignored_packages": ["Vintage"]
}
1
2
3
4
5
6

# 输入法问题解决

如果大家和我一样使用的输入法是 fcitx 的话可以使用 fcitx 官方提供的解决办法Hall_of_Shame_for_Linux_IME_Support (opens new window) 按照那个帖子 (opens new window)三个步骤便可以成功调出输入法.

# 常用插件推荐

# Package Control

Package Control 是用来管理 Sublime Text 2 的插件的插件. 也是装完后第一个要安装的插件. 首先打开 console, 并在打开的 Sublime console 中输入:

import urllib2,os; pf='Package Control.sublime-package'; ipp=sublime.installed_packages_path(); os.makedirs(ipp) if not os.path.exists(ipp) else None; urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler())); open(os.path.join(ipp,pf),'wb').write(urllib2.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read()); print 'Please restart Sublime Text to finish installation'
1

# ZenCoding

Zen Coding 是为了高速 HTML 编程和编辑开发的插件。这个插件的核心是一个超级强大的缩略词引擎,允许你扩展表达式到 HTML 代码中,类似于 CSS 的选择器。 通过 Ctrl+, 进行代码展开

Zen Coding 现在已经被 Emmet 替代(Zen Coding 已经从 Sublime Text 2 的插件源中移除),直接在编辑器内输入表达式,按下 Tab 即可扩展。

# jQuery Package for Sublime Text

这个毫无疑问,没有 jQuery 我们还能干什么?绝对不错的 jQuery 开发插件,个人来说非常喜欢.

# JS Format

JS format 是 Sublime Text 2 的一个 javascript 的格式化插件,使用来自 JS beautifier 的命令行/python 模块的 javascript 格式来格式化选择的文本,或者整个文件. 不过貌似格式化部分文本会出现问题

# Sublime CodeIntel

是一个想法来自于 Komodo 编辑器的智能插件. 帮助你实时展示存在模块的自动补齐信息,同时也展示目前方法的信息到状态栏中. 自动补全超赞的!

# Tag

当你需要处理标签时,Tag 是一个伟大的插件.

# 解决中文编码问题

ConvertToUTF8 (opens new window) Codecs26 (opens new window) 同时装这两个插件就可以正常打开 GBK 文件并且保存.

# 一些编码规范

有时候会设置保存文件时删除多余的空白字符并且在文件结尾添加空白行

打开 Preferences->Settings-Default 设置

"trim_trailing_white_space_on_save": true,
"ensure_newline_at_eof_on_save": true,
1
2

Ubuntu下apache2的配置记录

自从 2012 年四月买 VPS...到现在已经算是一年多了吧.在此感谢琴对我的帮助和指导.没有琴的指导我也不会折腾和配置 VPS. 期间一点一点的成长都离不开大家的帮助.不过对琴的过度依赖,使我一度成为伸手党...真是十分抱歉 QAQ 现在写一篇日志记录下 apache2 的配置方法也可以留着自己以后进行参考.

# 安装 apache 套装

首先安装 lampsudo apt-get install lamp-server^PHP 开发和服务器运行环境首选 LAMP 组合,即 Linux+Apache+Mysql+Php/Perl/Python,能最优化服务器性能

# 开启相关模块

启用 mod_rewrite 模块

sudo a2enmod rewrite
1

启用 mod_proxy 模块

sudo a2enmod proxy
sudo a2enmod proxy_http
1
2

启用 SSL 模块

sudo a2enmod ssl
1

a2xx 系列的命令共有 a2dismod、a2enmod、a2dissite、a2ensite,作用分别是禁用模块、启用模块、停用站点、启用站点这些命令简单得连--help 选项都没有,只能运行看提示。其作用也很简单,就是在/etc/apache2/mods-enabled 和/etc/apache2/sites-enabled 里面建立或删除相对应的 x-available 目录里面的模块的链接。

# 具体相关配置

服务器资源一般很高贵,大家都会挂很多独立站点的.apache2 默认存放网站的目录是 /var/www 配置文件储存在 /etc/apache2 主配置文件在 apache2.conf 其中这个配置文件包含了 sites-enabled 目录 这个目录是主要储存配置文件的地方 配置文件以 000-default 000-default-ssl 这种命名方式进行命名. 这两个文件是对 http 和 https 进行默认配置.下面我们来看看这两个默认配置 vim 000-default

<VirtualHost *:80>
ServerAdmin acgotaku311@email.me
    ServerName _default_
DocumentRoot /var/www/default
<Directory />
  Options FollowSymLinks
  AllowOverride None
</Directory>
<Directory /var/www/default>
  Options Indexes FollowSymLinks MultiViews
  AllowOverride None
  Order allow,deny
  allow from all
</Directory>

ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
  AllowOverride None
  Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
  Order allow,deny
  Allow from all
</Directory>

ErrorLog ${APACHE_LOG_DIR}/error.log

# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn

CustomLog ${APACHE_LOG_DIR}/access.log combined

Alias /doc/ "/usr/share/doc/"
<Directory "/usr/share/doc/">
    Options Indexes MultiViews FollowSymLinks
    AllowOverride None
    Order deny,allow
    Deny from all
    Allow from 127.0.0.0/255.0.0.0 ::1/128
</Directory>

</VirtualHost>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

第一行指定的是服务使用的端口. 第二行 ServerAdmin 写的是服务器管理员的邮箱. 第三行 ServerName 写的是服务器的名字 _default_ 代表默认使用这个, 即服务器名字找不到对应的配置文件的时候使用此配置文件. 第四行 DocumentRoot 写的是网站的根目录,即输入网址映射到服务器具体的哪个站点. Directory 子节点是对具体目录进行配置 我们主要是对网站根目录进行权限的配置. 其中主要说明的是 AllowOverride 选项 AllowOverride 控制那些被放置在 .htaccess 文件中的指令. 其余的配置基本不需要关心, vim 000-default-ssl

<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerAdmin acgotaku311@email.me
    ServerName  _default_
DocumentRoot /var/www/default
<Directory />
  Options FollowSymLinks
  AllowOverride None
</Directory>
<Directory /var/www/default>
  Options Indexes FollowSymLinks MultiViews
  AllowOverride All
  Order allow,deny
  allow from all
</Directory>

ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
  AllowOverride None
  Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
  Order allow,deny
  Allow from all
</Directory>

ErrorLog ${APACHE_LOG_DIR}/error.log

# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn

CustomLog ${APACHE_LOG_DIR}/ssl_access.log combined

Alias /doc/ "/usr/share/doc/"
<Directory "/usr/share/doc/">
  Options Indexes MultiViews FollowSymLinks
  AllowOverride None
  Order deny,allow
  Deny from all
  Allow from 127.0.0.0/255.0.0.0 ::1/128
</Directory>

#   SSL Engine Switch:
#   Enable/Disable SSL for this virtual host.
SSLEngine on

SSLCertificateFile    /etc/apache2/ssl/ssl.crt
SSLCertificateKeyFile /etc/apache2/ssl/ssl.key


<FilesMatch "\.(cgi|shtml|phtml|php)$">
  SSLOptions +StdEnvVars
</FilesMatch>
<Directory /usr/lib/cgi-bin>
  SSLOptions +StdEnvVars
</Directory>

BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown

</VirtualHost>
</IfModule>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

SSL 模块就是多了一个证书的设置, 其余的基本不变.

其它站点基本就是拷贝默认的配置文件修改 ServerName 和 DocumentRoot 即可.

# 关于 SSL 证书

生成 SSl 证书命令

openssl genrsa -des3 -out ssl.key 1024
1

然后他会要求你输入这个 key 文件的密码。不推荐输入。 但是生成时候必须输入密码。你可以输入后 再删掉。

mv ssl.key xxx.key
openssl rsa -in xxx.key -out ssl.key
rm xxx.key
1
2
3

然后根据这个 key 文件生成证书请求文件openssl req -new -key ssl.key -out ssl.csr以上命令生成时候要填很多东西 一个个看着写吧(可以随便,毕竟这是自己生成的证书)最后根据这 2 个文件生成 crt 证书文件

openssl x509 -req -days 365 -in ssl.csr -signkey ssl.key -out ssl.crt
1

这里 365 是证书有效期 推荐 3650 哈哈。这个大家随意。最后使用到的文件是 key 和 crt 文件。

这里生成的证书是不受信任的...我们可以在Let's Encrypt (opens new window)上申请免费的证书.

关于微云下载的那点事

貌似腾讯公司出品了一个叫微云 (opens new window)的东东,说实话,要不是基家上某人告诉我我还真不知道== 然后就说说这个东西的事情了,貌似下载的时候只能给出下载页面的链接...故意把真实的下载地址隐藏了,而且分析到下载地址还不行 还得带 cookies 才行....咳咳,我就不说啥腾讯的坏话了,大家都懂的.然后就是下载页面上还有个举报按钮!我勒个去...分享河蟹的东西的时候就经常被爆菊了...

于是需求就来了,分析下载页面得出真正的下载地址和 cookies,让用户点击下载链接即可下载,既方便用户又免得被爆菊... 然后看了下页面的 JS... qqdisk_web_outlink.js qqdisk_web_wy.js qqviplib_2.0.0.js 三个主要的 JS 都压缩了 看着就想吐... 于是换了一个思路,F12 开启 chromium 的调试工具,在 Network 面板下查看网页到底和服务器发生了哪些交互 chromium 的开发工具非常明确的红色的标注了发生 POST 请求的链接.一眼就看到了. 测试用下载链接 (opens new window) 在这个页面载入的时候可以很清楚的看到网页对http://web.cgi.weiyun.com/wy_web.fcg (opens new window)这个网址进行 POST 请求,提交的表单是个 json 对象

{
  "req_header": {
    "proto_ver": 10006,
    "main_v": 12,
    "sub_v": 1,
    "encrypt": 0,
    "msg_seq": 1,
    "source": 30006,
    "token": "4d3754f563ad04a56fece81bbcc83302",
    "client_ip": "127.0.0.1",
    "cmd": "decode_url"
  },
  "req_body": {
    "url": "Q69+qVhF33RXX+jAvhRil4kmLW5GIZRW8Zd13MWsUyvzpcDLunyFPxcqaLdUNtq5FfLp9Oj65Xr2XxTn298qsOWHWHqVdGuP7q1xMT4Do/y34dP00q4H7gpr94udJr/d2H23l0QGIKteptOEY1bTYLwkc+BRRdYEFvNb36XnUMBrS8pMf8RqoLJiAPrbXgYeBFvAwJu13QPHiQOe2lxS2i+V7/UDRpJr2qz8FqnOTHSQhaNXD+8s7uZIyaWH8INMc1Ls9Ay1XOc="
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

上面的 JSON 对象里面只有 token 和 url 是可变的,其它都是固定值,仔细分析页面上的那三个压缩过的 JS 便可以得到答案. url 明显就是网址上问号后面的参数,我就不赘述了.关于 token,仔细分析发现 var _token=QQVIP.security.getAntiCSRFToken(); 了这段代码,也就是说腾讯还专门防止 CSRF(跨站点请求伪造),可是... 这个 token 值我随便填写也能成功返回结果 == 看来腾讯的程序员偷工减料了(又是临时工的错!) 只能说这里预留了一个接口,但是没做,仔细查了一下腾讯的那个函数并自己修改了一下

var CONST_SALT = 5381;
var CONST_MD5_KEY = 'tencentQQVIP123443safde&!%^%1282';
function getAntiCSRFToken(objConfig) {
  objConfig = objConfig || {};
  var salt = objConfig.salt || CONST_SALT;
  var skey = objConfig.skey || '';
  //QZFL.cookie.get("skey")
  var md5key = objConfig.md5key || CONST_MD5_KEY;
  var hash = [],
    ASCIICode;
  hash.push(salt << 5);
  for (var i = 0, len = skey.length; i < len; ++i) {
    ASCIICode = skey.charAt(i).charCodeAt();
    hash.push((salt << 5) + ASCIICode);
    salt = ASCIICode;
  }
  var md5str = $.md5(hash.join('') + md5key);
  return md5str;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

看来做的还是不错的,用 cookies 生成 token,但是你的"skey"的 cookies 是空的要闹哪样 == 基本上 token 就是个定值

4d3754f563ad04a56fece81bbcc83302
1

接下来看返回回来的 json 对象

{
  "rsp_body": {
    "dk": "3540da0c9b7db5fb4f26f2baea50ef60",
    "dl_cookie_name": "FTN5K",
    "dl_cookie_value": "8eb5b2ee",
    "dl_encrypt_url": "da42a15644a68baa30e174d7ed580165176d66c912d9eb235bb4d01363a32e739fc68cab7402869010e99ab64d899c2dd537b2ffc39e3464732acc7ac1413ec4",
    "dl_remain": 99997,
    "dl_svr_host": "hz.yun.ftn.qq.com",
    "dl_svr_port": 80,
    "eptm": "1398678922",
    "fd": "6385d50b-1be5-436a-8430-43f53b583922",
    "nickname": "─╄OvЁ1颗心只为ㄚòu",
    "nm": "CC女王.ssf",
    "realnm": "CC女王.ssf",
    "sha": "f9800d2bd0fa71c2506c5c305c2b50988eb5b2ee",
    "shorturl": "http://url.cn/A8Clnw",
    "sz": "145195",
    "uin": 215629877
  },
  "rsp_header": {
    "cmd": "decode_url",
    "msg_seq": 1,
    "ret": 0,
    "uin": 215629877
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

这里我只关心下载有关的参数,其它参数大家可以自行猜测,dl_cookie_name 和 dl_cookie_value 是所需要的 cookies 的键值对.

'http://' +
  json.rsp_body.dl_svr_host +
  ':' +
  json.rsp_body.dl_svr_port +
  '/ftn_handler/' +
  json.rsp_body.dl_encrypt_url +
  '/' +
  json.rsp_body.realnm;
1
2
3
4
5
6
7
8

这就是根据 JSON 拼接出来的下载链接 接下来的问题就是 cookies 跨越问题了,点击页面上的下载按钮可以发现,页面与服务器又发生了交互. 页面向http://web.weiyun.qq.com/php/downloadCheck.php (opens new window)提交了 downloadn=FTN5K&downloadv=8eb5b2ee 这个正是 cookies 的键值对,后面的 callback 是 JQUery 回调的参数,无视就可以了,关键是服务器返回的 Respose Headers

Set-Cookie:FTN5K=8eb5b2ee; expires=Mon, 29-Apr-2013 11:51:48 GMT; path=/; domain=qq.com
1

这样就写入了 cookies,因为是 GET 方法提交的请求,这样就可以使用跨域请求.完成 cookies 的跨越注入.具体使用方法是

var downloadcookie =
  'http://web.weiyun.qq.com/php/downloadCheck.php?downloadn=' +
  json.rsp_body.dl_cookie_name +
  '&downloadv=' +
  json.rsp_body.dl_cookie_value;
var d = document;
var s = d.createElement('script');
s.src = downloadcookie;
d.body.appendChild(s);
1
2
3
4
5
6
7
8
9

通过 src 可以向http://web.weiyun.qq.com (opens new window)发送 GET 请求,就完成了跨越的 cookies 注入.注意跨越请求只能支持 GET 方法,POST 是绝对不可能实现跨越请求的. 但是调试的时候需要 POST 跨越请求怎么办,最简单的办法是在启动浏览器的时候添加启动方法 chromium --disable-web-security 这样浏览器就不会阻止 跨越的 POST 请求,否则就会 console 出现下面的红色错误提示.

XMLHttpRequest cannot load http://web.cgi.weiyun.com/wy_web.fcg. Origin null is not allowed by Access-Control-Allow-Origin.
1

这样就下载页面分析下载链接就完成了,然后基友说微云的下载链接有两种还有一中是这个 (opens new window) 不是 outlink 而是 sharekey 了,其实就是格式变了而已....腾讯也不想在写一套解析办法吧 == 提交的 JSON 对象变成

{
  "req_header": {
    "net_type": 3,
    "build_v": 123,
    "proto_ver": 10006,
    "main_v": 12,
    "sub_v": 1,
    "encrypt": 0,
    "msg_seq": 1,
    "source": 30006,
    "token": "4d3754f563ad04a56fece81bbcc83302",
    "client_ip": "127.0.0.1",
    "cmd": "get_share_info",
    "uin": 0
  },
  "req_body": {
    "share_key": "a86487d6aa48e33429e0be477a87dc21"
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

然后提交的网址变成http://web.cgi.weiyun.com/wy_share.fcg (opens new window)返回的 JSON 对象是:

{
  "rsp_body": {
    "createtime": "2013-04-25 13:50:09",
    "data": "xfjJXsNsySkhhwT5SvFC7j85IjXqTxmV9RBC+mcIk1MOmMi0G68fkDTQulEHnBwSPO3Zs/6oAR/k5WLMkpiezA2NFpoCI1LRe2vrko9mMVrP1PcrGnJY26n7Iogto20Wq6aIBm7VjNI9+D2TmXWw4LodHzIf4VhMMGRDacvH04yd4+W/fwG6BbpQKOma42CbA4d8OGken8hNFnnxjE5QIO5GKCPjgsKpxQtPsM0nNbgvKfnLdcPrvcnT+Dm5ZQbZnkdj022QE2ZzXGNfX0c1IA==",
    "dir_list": [],
    "dl_cookie_name": "FTN5K",
    "dl_cookie_value": "2bc024b4",
    "dl_encrypt_url": "a85801ad13f6c92de0de07f0b0c1002d11b438dcfe7a63de37dce08e9a0db51b0789677db4a256a57085b66b52ebe680ab796e9f5c844e620884a443b397339e",
    "dl_svr_host": "tj.yun.ftn.qq.com",
    "dl_svr_port": 80,
    "downcnt": 19,
    "file_list": [
      {
        "file_id": "2bf60c0a-8694-4d08-bcb3-90e267b32691",
        "file_name": "逆転電池.rar",
        "file_size": "7163756"
      }
    ],
    "flag": 1,
    "pdir_key": "9c9bbd18f0a739ae12b58dcd423dce4a",
    "ppdir_key": "9c9bbd18f338fdcb41c5dfa52b9ed888",
    "res_type": 0,
    "sharename": "逆転電池.rar",
    "storecnt": 0,
    "uin": 415079324,
    "url": "http://url.cn/BKueJM",
    "viewcnt": 83
  },
  "rsp_header": {
    "cmd": "get_share_info",
    "ret": 0
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

这样就是真的完工了~