0%

函数节流

函数节流:就是函数按照一个周期执行,例如给window绑定一个resize事件之后,只要window大小改变就打印1, 如果不采用函数节流,当我们将窗口调节的时候发现控制台一直打印1,但是使用了函数节流后我们会发现调节的过程中,每隔一段时间才打印1。

1
2
3
4
5
6
7
8
9
10
var throttle = function(delay, cb) {
var startTime = Date.now();
return function() {
var currTime = Date.now();
if (currTime - startTime > delay) {
cb();
startTime = currTime;
}
}
}

函数去抖

函数去抖:就是当事件触发之后,必须等待某一个时间之后,回调函数才会执行,假若再等待的时间内,事件又触发了则等待时间刷新。 还是上面那个例子,如果我们一直改变窗口大小,则不会打印1,只有当我们停止改变窗口大小并等待一段时间后,才会打印1。

1
2
3
4
5
6
7
8
9
var debounce = function(delay, cb) {
var timer;
return function() {
if (timer) clearTimeout(timer);
timer = setTimeout(function() {
cb();
}, delay);
}
}

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
/**
* 时间对象的格式化;
*/
Date.prototype.format = function(format) {
/*
* eg:format="yyyy-MM-dd hh:mm:ss";
*/
var o = {
"M+" : this.getMonth() + 1, // month
"d+" : this.getDate(), // day
"h+" : this.getHours(), // hour
"m+" : this.getMinutes(), // minute
"s+" : this.getSeconds(), // second
"q+" : Math.floor((this.getMonth() + 3) / 3), // quarter
"S" : this.getMilliseconds()
// millisecond
}

if (/(y+)/.test(format)) {
format = format.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
}

for (var k in o) {
if (new RegExp("(" + k + ")").test(format)) {
format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length));
}
}
return format;
}

Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。 可查看RFC2045~RFC2049,上面有MIME的详细规范。

标准的Base64并不适合直接放在URL里传输,因为URL编码器会把标准Base64中的/+字符变为形如%XX的形式, 而这些%号在存入数据库时还需要再进行转换,因为ANSI SQL中已将%号用作通配符。

为解决此问题,可采用一种用于URL的改进Base64编码,它在末尾填充’=’号, 并将标准Base64中的+/分别改成了-_,这样就免去了在URL编解码和数据库存储时所要作的转换, 避免了编码信息长度在此过程中的增加,并统一了数据库、表单等处对象标识符的格式。

另有一种用于正则表达式的改进Base64变种,它将+/改成了!-, 因为+,*以及前面在IRCu中用到的[]在正则表达式中都可能具有特殊含义。

此外还有一些变种,它们将+/改为_-._(用作编程语言中的标识符名称) 或.-(用于XML中的Nmtoken)甚至_:(用于XML中的Name)。

Base64要求把每三个8Bit的字节转换为四个6Bit的字节(3*8 = 4*6 = 24),然后把6Bit再添两位高位0, 组成四个8Bit的字节,也就是说,转换后的字符串理论上将要比原来的长1/3。

Read more »

最近有一些朋友常问我一些乱码的问题,和他们交流过程中,发现这个编码的相关知识还真是杂乱不堪, 不少人对一些知识理解似乎也有些偏差,网上百度,google的内容,也有不少以讹传讹, 根本就是错误的(例如说 unicode编码是两个字节),各种软件让你选择编码的时候,常常是很长的一个选单,让用户不知道该如何选。 基于这样的问题,我就写下我的理解吧,一方面帮助一些需要帮助的人纠正认识,一方面作为自己以后备查的资料。

ASCII(American Standard Code for Information Interchange)

美国信息交换标准代码,这是计算机上最早使用的通用的编码方案。 那个时候计算机还只是拉丁文字的专利,根本没有想到现在计算机的发展势头,如果想到了,可能一开始就会使用unicode了。 当时绝大部分专家都认为,要用计算机,必须熟练掌握英文。 这种编码占用7个Bit,在计算机中占用一个字节,8位,最高位没用,通讯的时候有时用作奇偶校验位。 因此ASCII编码的取值范围实际上是:0x00-0x7f,只能表示128个字符。 后来发现128个不太够用,做了扩展,叫做ASCII扩展编码,用足八位,取值范围变成:0x00-0xff,能表示256个字符。 其实这种扩展意义不大,因为256个字符表示一些非拉丁文字远远不够,但是表示拉丁文字,又用不完。 所以扩展的意义还是为了下面的ANSI编码服务。

ANSI(American National Standard Institite)

美国国家标准协会,也就是说,每个国家(非拉丁语系国家)自己制定自己的文字的编码规则,并得到了ANSI认可, 符合ANSI的标准,全世界在表示对应国家文字的时候都通用这种编码就叫ANSI编码。 换句话说,中国的ANSI编码和在日本的ANSI的意思是不一样的,因为都代表自己国家的文字编码标准。 比如中国的ANSI对应就是GB2312标准,日本就是JIT标准,香港,台湾对应的是BIG5标准等等。 当然这个问题也比较复杂,微软从95开始,用就是自己搞的一个标准GBK。GB2312里面只有6763个汉字,682个符号,所以确实有时候不是很够用。 GBK一直能和GB2312相互混淆并且相安无事的一个重要原因是GBK全面兼容GB2312,所以没有出现任何冲突, 你用GB2312编码的文件通过GBK去解释一定能获得相同的显示效果,换句话说:GBK对GB2312就是,你有的,我也有,你没得的,我还有!

Read more »

准备

  1. 安装Docker
  2. 安装Docker-compose
  3. 拉取镜像:nginxcertbot/certbot
  4. 域名your.domain.com

部署

从nginx镜像中复制nginx.conf文件

1
2
3
docker run --name tmp-nginx-container -d nginx
docker cp tmp-nginx-container:/etc/nginx/nginx.conf `pwd`/nginx.conf
docker rm -f tmp-nginx-container

配置your.domain.com的http服务

1
2
3
4
5
6
7
8
9
10
11
server {
listen 80;
server_name your.domain.com;

location ^~ /.well-known/acme-challenge/ {
root /usr/share/nginx/html;
}
location / {
rewrite ^/(.*)$ https://$server_name/$1 permanent;
}
}

配置docker-compose.yaml文件

1
2
3
4
5
6
7
8
9
10
11
12
13
version: "2"
services:
nginx:
image: nginx
restart: always
ports:
- 80:80
- 443:443
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./conf.d:/etc/nginx/conf.d
- ./letsencrypt:/etc/letsencrypt
- ./html:/usr/share/nginx/html

启动nginx服务

1
docker-compose up -d

生成Letsencrypt证书

1
2
3
4
5
6
docker run -it \
-v `pwd`/letsencrypt:/etc/letsencrypt \
-v `pwd`/html:/usr/share/nginx/html \
certbot/certbot \
certonly --webroot -w /usr/share/nginx/html/ \
-d your.domain.com

配置your.domain.com的https服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
server {
listen 443;
server_name your.domain.com;

ssl on;
ssl_certificate /etc/letsencrypt/live/your.domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your.domain.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/your.domain.com/chain.pem;

location ^~ /.well-known/acme-challenge/ {
root /usr/share/nginx/html;
}
location / {
root /usr/share/nginx/html;
}
}

重启nginx服务

1
docker-compose exec nginx nginx -s reload

刷新Letsencrypt证书

1
2
3
4
5
docker run -it \
-v `pwd`/letsencrypt:/etc/letsencrypt \
-v `pwd`/html:/usr/share/nginx/html \
certbot/certbot \
renew

建议每隔一个月刷新一次证书,将其写入定时任务。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
curl -o IntelliJIDEALicenseServer "http://home.ustc.edu.cn/~mmmwhy/86"
chmod a+x IntelliJIDEALicenseServer

cat <<EOF>> docker-compose.yaml
version: "2"
services:
IntelliJIDEALicenseServer:
image: ubuntu:16.04
restart: always
ports:
- 1234:1234
volumes:
- ./IntelliJIDEALicenseServer:/usr/bin/IntelliJIDEALicenseServer
command: IntelliJIDEALicenseServer -p 1234 -u admin
EOF

docker-compose up -d

Gogs是一个git server,下面是docker-compose.yaml文件:

1
2
3
4
5
6
7
8
9
version: "2"
services:
gogs:
image: gogs/gogs
restart: always
ports:
- 80:3000
volumes:
- ./data:/data

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
# 创建配置文件目录
mkdir configs

cat <<EOF>> configs/addresses.conf
# Add domains which you want to force to an IP address here.
# The example below send any host in double-click.net to a local
# web-server.
#address=/double-click.net/127.0.0.1

# --address (and --server) work with IPv6 addresses too.
#address=/www.thekelleys.org.uk/fe80::20d:60ff:fe36:f83
EOF

# 创建docker-compose.yml文件
cat <<EOF>> docker-compose.yml
version: "2"
services:
dnsmasq:
image: hypc/dnsmasq:2.76-alpine
ports:
- 53:53/tcp
- 53:53/udp
restart: always
volumes:
- ./configs:/etc/dnsmasq.d
cap_add:
- NET_ADMIN
EOF