unit8array转换为字符串

unit8array 格式是8字节无符号整数数组,如果把它转换为 string 类型呢?

  1. 如果不是 utf8 编码的话,可以用下面的方法:

    1
    2
    3
    function uint8arrToStr(uint8arr){
    return String.fromCharCode.apply(null, uint8arr)
    }
  2. 如果使用了 utf8 编码,在浏览器上可以用下面的方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    // 把 Uint8Array 转换为 String
    function uint8arrToStr(uint8arr){
    return new TextDecoder("utf-8").decode(uint8arr)
    }

    // 把 String 转换为 Uint8Array
    function str2Uint8arr(str){
    return new TextEncoder("utf-8").encode(str)
    }

Read More

utf16转换为utf8

如何把 utf16 编码的字符串转换为 utf8 呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function utf16to8(str) {
var out, i, len, c;

out = "";
len = str.length;
for(i = 0; i < len; i++) {
c = str.charCodeAt(i);
if ((c >= 0x0001) && (c <= 0x007F)) {
out += str.charAt(i);
} else if (c > 0x07FF) {
out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
} else {
out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
}
}
return out;
}

Read More

用docker申请letsencrypt通配符证书

用 docker 申请 letsencrypt 证书的好处就是不需要在宿主机上安装依赖,只要用下面的命令即可:

1
2
3
4
5
6
docker run -it --rm \
--name certbot \
-v /mnt/letsencrypt:/etc/letsencrypt \
-v /mnt/bak/letsencrypt:/var/lib/letsencrypt \
certbot/certbot \
certonly --manual --agree-tos --server https://acme-v02.api.letsencrypt.org/directory --preferred-challenges dns -d *.YOUR-DOMAIN.com -d YOUR-DOMAIN.com

具体的命令释义如下:

1
2
3
4
5
6
-v /mnt/letsencrypt:/etc/letsencrypt -v /mnt/bak/letsencrypt:/var/lib/letsencrypt # 挂载目录,certbot申请到的或备份的证书会放在这两个目录
--manual # 交互模式
--agree-tos # 同意服务协议
--server https://acme-v02.api.letsencrypt.org/directory # 指定使用acmev2协议的服务器,因为通配符证书的申请需要这个协议
–preferred-challenges dns # 使用dns检验来证明你拥有这个域名
-d *.YOUR-DOMAIN.com -d YOUR-DOMAIN.com # 指定了需要申请证书的通配符域名,根域名要额外再写一次

Read More

axios 请求 https 证书错误解决方案

使用 axios 请求 https 网站的数据时,报错:

1
Error: certificate has expired

可以使用下面的方法忽略证书错误:

1
2
3
4
5
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; // 不拒绝过期的和无效的证书
const agent = new https.Agent({
rejectUnauthorized: false
})
axios.get('https://something.com/foo', { httpsAgent: agent })

jenkins 学习笔记

这里采用 docker 容器来安装和部署 jenkins,首先下载官方镜像:

1
docker pull jenkins/jenkins:lts

然后启动:

1
2
3
4
5
6
7
8
9
# 临时运行
docker run -p 8080:8080 -p 50000:50000 jenkins/jenkins:lts

# 长期维护
docker volume create jenkins-data # 创建数据卷
docker run -d -p 8080:8080 -p 50000:50000 \
-v jenkins-data:/var/jenkins_home \
--name jenkins \
jenkins/jenkins:lts

然后命令行会随机生成管理员密码,先记下来,如果忘了,也可以用下面的命令查看:

1
cat /var/jenkins_home/secrets/initialAdminPassword

Read More

yarn 安装时出现 node incompatible

今天用 yarn 安装依赖失败,报下面的错:

1
The engine "node" is incompatible with this module. Expected version ">=4 <=9". Got "10.14.2"

网上很多人说用 yarn --ignore-engines 可以解决这个问题,然而这样做是有风险的。这个问题产生的原因是依赖包 upath 导致的,它在 package.json 里面限制 node engine 只能是 4~9 版本的,只要把 upath 给升级就行了,解决方法如下:

1
2
3
rm -rf node_modules/
rm yarn.lock
yarn install

这样就会更新 upath 到最新版本。

centos 安装 mozjpeg

首先安装 nasm 环境:

1
yum -y install build-essential nasm libtool

然后下载源码编译:

1
2
3
4
5
6
7
wget https://github.com/mozilla/mozjpeg/archive/v3.3.1.zip
unzip v3.3.1.zip
cd mozjpeg-3.3.1
autoreconf -fiv
./configure
make
make install

安装后的可执行文件所在的目录是 /opt/mozjpeg/bin

1
2
3
4
5
6
7
8
[root@VM_156_24_centos mozjpeg-3.3.1]# ls -hl /opt/mozjpeg/bin
总用量 268K
-rwxr-xr-x 1 root root 56K 1月 23 10:04 cjpeg
-rwxr-xr-x 1 root root 45K 1月 23 10:04 djpeg
-rwxr-xr-x 1 root root 53K 1月 23 10:04 jpegtran
-rwxr-xr-x 1 root root 14K 1月 23 10:04 rdjpgcom
-rwxr-xr-x 1 root root 63K 1月 23 10:04 tjbench
-rwxr-xr-x 1 root root 14K 1月 23 10:04 wrjpgcom

a.jpg 按照 80% 的压缩率保存到 a1.jpg

1
/opt/mozjpeg/bin/cjpeg -quality 80 a.jpg > a1.jpg

cjpeg 默认的压缩率是 75%,-quality 参数可以自定义压缩率。

gulp 学习笔记

在 gulp 的任务中,gulp.src 接口将匹配到的文件转化为可读的文件流,通过 .pipe 流经各插件进行处理,最终推送给 gulp.dest 所生成的可写文件流,生成文件写入磁盘。其中涉及到下面几个重要的库:

Vinyl

Vinyl 是一个文件描述器,通过它可以在内存中构建临时文件对象。

1
2
3
const Vinyl = require('vinyl')
const empty = new Vinyl()
console.dir(empty)

最终打印出来:

1
2
3
4
5
6
7
File {
stat: null,
_contents: null,
history: [],
_cwd: '/job/gulp-tutorial',
_isVinyl: true,
_symlink: null }

Read More

Angular 中 video 自动静音播放

在页面里面加了一个 video,想让这个视频在页面加载之后自动播放,用下面的写法:

1
2
3
4
5
6
7
8
9
10
11
 <video
id="officeVideo"
preload="metadata"
poster="assets/media/office.jpg"
playsinline
autoplay
muted
loop
>
<source src="assets/media/office.mp4" type="video/mp4" />
</video>

但是在谷歌浏览器下测试,发现第一次可以自动播放,再刷新就暂停了,很奇怪,网上找了一些解决方案开始尝试,例如下面的代码用 jQuery 找到这个 video 元素,手动调用 play 函数:

1
2
3
const el = $('#officeVideo')
const video = el.get(0)
video.play()

Read More

syslog 学习笔记

syslog 服务器可以用作日志监控中心,这样更容易地查看和获取重要的日志消息。rsyslog 是 syslog 的守护进程,预装在了大多数的Linux发行版中,扮演了两种角色:

  1. 作为服务器收集来自其他设施的日志信息;
  2. 作为客户端将其内部的日志信息传输到远程的 syslog 服务器。

相关文件的位置如下:

  • 执行文件: /sbin/rsyslogd
  • 主配置文件: /etc/rsyslog.conf
  • 自定义配置文件: /etc/rsyslog.d/*.conf

通过下面的命令可查看状态和重启服务:

1
2
service rsyslog status # 查看状态
/etc/init.d/rsyslog restart # 重启服务

Read More