为 Kindle 版微信读书替换衬线字体

date
Dec 24, 2022
slug
replace-weread-font-with-serif-for-kindle
status
Published
summary
我经常在微信读书读大部头,但是它的 Kindle 版本只能使用无衬线字体,总觉得差了点意思,于是就动了改造的念头。使用到了 nginx 反向代理技术和 sub_filter 内容替换模块。
tags
Engineering
Reading
type
Post

起因

我经常在微信读书读大部头,但是它的 Kindle 版本只能使用无衬线字体,总觉得差了点意思,于是就动了改造的念头。

改造效果

notion image

实现方案

简单来说就是自己通过 nginx 的反向代理能力,修改微信读书的样式,让字体成为 Kindle 内置的衬线字体。
  • 应用的 CSS 样式:
    • font-weight: 500;
      font-family: Baskerville, serif, STSong !important
  • 前置条件:
    • 自有域名
    • 安装了 nginx 的服务器一台
  • 交互如下:
notion image

具体步骤

一、编译 nginx 使其支持替换模块

  1. 查询系统安装的 nginx 版本和编译参数,通过nginx -V 可以看到我的版本和参数
nginx version: nginx/1.18.0
built by gcc 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1) 
built with OpenSSL 1.1.1f  31 Mar 2020
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-lUTckl/nginx-1.18.0=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-compat --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_xslt_module=dynamic --with-stream=dynamic --with-stream_ssl_module --with-mail=dynamic --with-mail_ssl_module
  1. 下载对应的 nginx 版本,我的是 1.18.0 所以下载这个文件:
    1. wget http://nginx.org/download/nginx-1.18.0.tar.gz
  1. 解压 nginx 文件并进入解压文件夹,也是和你的版本号有关:
    1. tar -xavf nginx-1.18.0.tar.gz
      cd nginx-1.18.0
  1. 克隆模块代码仓库:
    1. git clone https://github.com/yaoweibin/ngx_http_substitutions_filter_module
  1. 编译并安装,只需要在原有编译参数后添加 --add-module=./ngx_http_substitutions_filter_module 即可:
./configure --with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-lUTckl/nginx-1.18.0=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-compat --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_xslt_module=dynamic --with-stream=dynamic --with-stream_ssl_module --with-mail=dynamic --with-mail_ssl_module --add-module=./ngx_http_substitutions_filter_module
  1. (不一定需要)如果这时候报错,说明部分需要的库你没有安装,安装即可,我额外安装了
    1. apt-get install build-essential
      apt install libxml2 libxml2-dev libxslt-dev
      apt install libgd-dev
  1. 确定 nginx 位置,使用whereis nginx 即可看到,
    1. 我的在 /usr/sbin/nginx 这个位置
  1. 替换 nginx 执行文件,
    1. cp ./objs/nginx /usr/sbin/nginx

二、设置域名和申请证书

为了快速输入我们的地址,需要绑定域名:
  • r.yourdomain.com 为主要访问服务器,指向你的服务器地址;
  • read.yourdomain.comres.yourdomain.comwereadsource.yourdomain.com 为静态资源服务器,指向你的服务器地址;
证书的获取参考其他教程,不做赘述,建议使用 acme.sh,省心。

三、Nginx 新增站点配置

在 Nginx 配置文件目录(默认位于 /etc/nginx/sites-enabled/ )新增 read.conf 微信阅读反代配置文件,文件内容如下(需自行替换 yourdomain.com 域名和对应证书路径):
server { 
    listen 80;
    server_name read.yourdomain.com;
    location / {
          rewrite ^/(.*)$ https://read.yourdomain.com$1 permanent;
    }
}
server { 
    listen 80;
    server_name r.yourdomain.com;
    location / {
          rewrite ^/(.*)$ https://read.yourdomain.com/wrwebsimplenjlogic/login permanent;
    }
}
server { 
    listen 80;
    server_name wereadsource.yourdomain.com;
    location / {
          rewrite ^/(.*)$ https://wereadsource.yourdomain.com$1 permanent;
    }
}

server { 
	listen  443 ssl;
	listen  [::]:443 ssl;
	server_name  r.yourdomain.com;     # Your domain.
    ssl_certificate      /root/.acme.sh/*.yourdomain.com/fullchain.cer;
    ssl_certificate_key  /root/.acme.sh/*.yourdomain.com/*.yourdomain.com.key;
    
	ssl_session_timeout  10m;
	ssl_ciphers HIGH:!aNULL:!MD5;
	ssl_prefer_server_ciphers on;
    location / {
          rewrite ^/(.*)$ https://read.yourdomain.com/wrwebsimplenjlogic/login permanent;
    }
}
server {
	listen  443 ssl;
	listen  [::]:443 ssl;
	server_name  read.yourdomain.com;     # Your domain.
    ssl_certificate      /root/.acme.sh/*.yourdomain.com/fullchain.cer;
    ssl_certificate_key  /root/.acme.sh/*.yourdomain.com/*.yourdomain.com.key;
    
	ssl_session_timeout  10m;
	ssl_ciphers HIGH:!aNULL:!MD5;
	ssl_prefer_server_ciphers on;

    if ( $host != "read.yourdomain.com" ) {
        return 403; 
    }

    # proxy_intercept_errors on;
    # error_page 301 302 307 = @handle_redirects;

    # location @handle_redirects {
    # proxy_redirect https://weread.qq.com/web/ https://weread.qq.com/web/;
    # # proxy_redirect https://weread.qq.com/ /;
    # }

    location / {
        # proxy_intercept_errors on;
        # error_page 301 302 307 = @handle_redirects;
        proxy_redirect off;
        proxy_cookie_domain weread.qq.com read.yourdomain.com; 
        proxy_pass https://weread.qq.com;
        proxy_connect_timeout 60s;
        proxy_read_timeout 5400s;
        proxy_send_timeout 5400s;
        proxy_set_header Host weread.qq.com;
        # proxy_set_header User-Agent "Mozilla/5.0 (X11; ; U; Linux armv7l like Android; en-us) AppleWebKit/531.2+ (KHTML, like Gecko) Version/5.0 Safari/533.2+ Kindle/3.0+";
        proxy_set_header User-Agent $http_user_agent;
        proxy_set_header Referer https://weread.qq.com;
        proxy_set_header Accept-Encoding "";
        proxy_set_header X-Real-IP $remote_addr; 
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
        proxy_set_header X-Forwarded-Proto https;
        # proxy_set_header Accept-Language "zh-CN";
        # sub_filter_once off; 
        subs_filter_types text/css text/xml application/javascript text/javascript;
        subs_filter "res.weread.qq.com" "res.yourdomain.com" gi;
        subs_filter "weread.qq.com" "read.yourdomain.com" gi;
        subs_filter "weread-1258476243.file.myqcloud.com" "wereadsource.yourdomain.com" gi;
        subs_filter "https://weread.qq.com/wrwebsimplenjlogic/shelf" "https://read.yourdomain.com/wrwebsimplenjlogic/shelf" gi;
        subs_filter "<title>微信读书" "<title>微信读书" gi;
        subs_filter "</html>" "<style> * {font-weight: 500; font-family: Baskerville, serif, STSong !important;}</style></html>" gi;
    }

    # location @handle_redirects {
    #     set $saved_redirect_location '$upstream_http_location';
    #     proxy_pass $saved_redirect_location;
    # }
}


server {
	listen  443 ssl;
	listen  [::]:443 ssl;
	server_name  wereadsource.yourdomain.com;     # Your domain.
    ssl_certificate      /root/.acme.sh/*.yourdomain.com/fullchain.cer;
    ssl_certificate_key  /root/.acme.sh/*.yourdomain.com/*.yourdomain.com.key;
    
	ssl_session_timeout  10m;
	ssl_ciphers HIGH:!aNULL:!MD5;
	ssl_prefer_server_ciphers on;
    if ( $host != "wereadsource.yourdomain.com" ) {
        return 403; 
    }
    location / {
        proxy_redirect off;
        proxy_cookie_domain weread-1258476243.file.myqcloud.com wereadsource.yourdomain.com; 
        proxy_pass https://weread-1258476243.file.myqcloud.com;
        proxy_connect_timeout 60s;
        proxy_read_timeout 5400s;
        proxy_send_timeout 5400s;
        proxy_set_header Host weread-1258476243.file.myqcloud.com;
        # proxy_set_header User-Agent "Mozilla/5.0 (X11; ; U; Linux armv7l like Android; en-us) AppleWebKit/531.2+ (KHTML, like Gecko) Version/5.0 Safari/533.2+ Kindle/3.0+";
        proxy_set_header User-Agent $http_user_agent;
        proxy_set_header Referer https://weread-1258476243.file.myqcloud.com;
        proxy_set_header Accept-Encoding "";
        proxy_set_header X-Real-IP $remote_addr; 
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
        proxy_set_header X-Forwarded-Proto https;
        # proxy_set_header Accept-Language "zh-CN";
        # sub_filter_once off; 
        subs_filter_types text/css text/xml application/javascript text/javascript;
        subs_filter "res.weread.qq.com" "res.yourdomain.com" gi;
        subs_filter "weread.qq.com" "read.yourdomain.com" gi;
        subs_filter "weread-1258476243.file.myqcloud.com" "wereadsource.yourdomain.com" gi;
        subs_filter "<title>微信读书" "<title>微信读书" gi;
        subs_filter "https://weread.qq.com/wrwebsimplenjlogic/shelf" "https://read.yourdomain.com/wrwebsimplenjlogic/shelf" gi;
    }
}

server {
	listen  443 ssl;
	listen  [::]:443 ssl;
	server_name  res.yourdomain.com;     # Your domain.
    ssl_certificate      /root/.acme.sh/*.yourdomain.com/fullchain.cer;
    ssl_certificate_key  /root/.acme.sh/*.yourdomain.com/*.yourdomain.com.key;
    
	ssl_session_timeout  10m;
	ssl_ciphers HIGH:!aNULL:!MD5;
	ssl_prefer_server_ciphers on;
    if ( $host != "res.yourdomain.com" ) {
        return 403; 
    }
    location / {
        proxy_redirect off;
        proxy_cookie_domain res.weread.qq.com res.yourdomain.com; 
        proxy_pass https://res.weread.qq.com;
        proxy_connect_timeout 60s;
        proxy_read_timeout 5400s;
        proxy_send_timeout 5400s;
        proxy_set_header Host res.weread.qq.com;
        # proxy_set_header User-Agent "Mozilla/5.0 (X11; ; U; Linux armv7l like Android; en-us) AppleWebKit/531.2+ (KHTML, like Gecko) Version/5.0 Safari/533.2+ Kindle/3.0+";
        proxy_set_header User-Agent $http_user_agent;
        proxy_set_header Referer https://res.weread.qq.com;
        proxy_set_header Accept-Encoding "";
        proxy_set_header X-Real-IP $remote_addr; 
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
        proxy_set_header X-Forwarded-Proto https;
        # proxy_set_header Accept-Language "zh-CN";
        # sub_filter_once off; 
        subs_filter_types text/css text/xml application/javascript text/javascript;
        subs_filter "res.weread.qq.com" "res.yourdomain.com" gi;
        subs_filter "weread.qq.com" "read.yourdomain.com" gi;
        subs_filter "res.weread.qq.com" "wereadsource.yourdomain.com" gi;
        subs_filter "<title>微信读书" "<title>微信读书" gi;
        subs_filter "https://weread.qq.com/wrwebsimplenjlogic/shelf" "https://read.yourdomain.com/wrwebsimplenjlogic/shelf" gi;
    }
}

四、重启 nginx

systemctl restart nginx 配置生效,访问 r.yourdomain.com 即可。


Reynard © 2021 - 2023

Powered byVercel