转载

让多说评论框完美支持 HTTPS

我的博客之前一直部署在 Linode,使用 Disqus 提供的评论服务。Disqus 作为第三方社会化评论的鼻祖,无论是功能还是体验,都堪称完美。虽然之前 Disqus 经常加载失败,我也一直在坚守。最近我的 Linode 持续无法访问,几番折腾之后还是换到国内云主机并备案了。借着这次机会,我也把评论从 Disqus 迁移到了国内的 多说 。多说官方对 HTTPS 的支持并不完美,本文记录我对它的几处改造。

Disqus 和多说都是根据指定 ID 进行评论聚合的第三方系统,将页面上 Disqus 的引用代码换成多说的代码,再按照文档改改参数,评论功能就迁移完成了。数据迁移可以使用前人造好的轮子,例如 Github 上的 GavinFoo/DISQUS2DUOSHUO 。功能和数据迁移都很简单,这里略过不写。

我的网站配置了CSP 策略,需要把多说用到的域名配置到白名单之中。以下是本站 CSP 全部规则:

content-security-policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: https://*.duoshuo.com; img-src 'self' data: https://*.duoshuo.com; style-src 'self' 'unsafe-inline' https://*.duoshuo.com; connect-src wss://*.duoshuo.com:* https://*.duoshuo.com 

多说的种子文件支持 HTTPS,直接把官方地址替换为 HTTPS 即可。但多说有几个地方没考虑周到,需要额外处理:1)用户头像,多说支持多种第三方登录方式,用户头像也支持使用了第三方地址,而这些地址基本都是 HTTP;2)表情,在多说选择表情的浮层中,只有 wordpress 分组中的表情放在多说服务器上并支持 HTTPS,其余分组全部直接使用了 Sina 微博的 HTTP 地址。另外多说评论正文中的表情,也需要替换为 HTTPS 地址。

要解决用户头像问题,可以借用本站 HTTPS 做一个反向代理。我在 Nginx 配置增加了以下内容:

proxy_cache_path    /home/jerry/cache/nginx/proxy_cache_path levels=1:2 keys_zone=pnc:300m inactive=30d max_size=10g; proxy_temp_path     /home/jerry/cache/nginx/proxy_temp_path; proxy_cache_key     $host$uri$is_args$args; server {     ... ...     location ~ ^/proxy/(/w+/.)(bdimg/.com|cdncache/.org|douban/.com|gravatar/.com|qlogo/.cn|sinaimg/.cn)(//.*)$ {  proxy_connect_timeout    10s;  proxy_read_timeout       10s;  proxy_pass        http://$1$2$3;  proxy_cache       pnc;  proxy_cache_valid 200 30d;  proxy_cache_lock  on;  proxy_cache_lock_timeout 5s;  proxy_cache_use_stale    updating error timeout invalid_header http_500 http_502;  add_header        X-Cache "$upstream_cache_status from cache.ququ";  expires    max;     }     location ~ ^/proxy/(.*)$ {  rewrite       ^.*$ /static/img/blog/default_avatar.png last;     }     ... ... }  

以上配置做了几件事情:1)针对白名单中的 URL 做了反向代理,针对白名单之外的 URL 输出默认头像;2)通过 Nginx 的 proxy_cache 以及 HTTP 的缓存机制,增加访问速度。

有了反向代理之后,可以对多说的 embed.js 动手术了。我没有找到无侵入的补丁方式,只能粗暴地将官方 embed.js 托管在本站进行修改。一共修改了以下几处(为了看得更清楚,我加入的代码放在注释里):

avatarUrl: function(e) {  /*  if (e.avatar_url) {   e.avatar_url = e.avatar_url.replace(/^http/://///, "https://imququ.com/proxy/");  } else {   nt.data.default_avatar_url = '/static/img/blog/default_avatar.png';  }  */  return e.avatar_url || nt.data.default_avatar_url }  

这处修改,是让多说用户头像走前面配置的 proxy 服务。对于无头像用户,我直接返回了默认头像地址,减少一次 proxy。

addSmilies = function(e, t) {  /*  if(e !== 'WordPress') return;  */  var s = j.smiliesTooltip;  s && s.el.find("ul.ds-smilies-tabs").append("<li><a>" + e + "</a></li>"), j.smilies[e] = t }  

这处修改,是让多说不加载 Wordpress 之外的分组表情。由于只剩下一个分组,所以表情浮层样式我也微调了一下,具体效果请看本文评论(实际上,多说评论的样式我改了好多处)。将 Sina 微博表情替换为 proxy 地址,或者是传到支持 HTTPS 的 CDN 也可以,但我觉得没有必要。如果图省事,也可以直接在多说后台关闭评论表情功能。

var t = "",  s = e.post,  i = e.options,  r = s.author; /* s.message = s.message.replace(/http:////static/.duoshuo/.com///g, 'https://static.duoshuo.com/'); */ if (t += '<li class="ds-post" data-post-id="' + s.post_id + '">...'){  ... }  

这处修改,是将评论内容中的表情地址由 HTTP 替换为 HTTPS。

经过以上处理,多说评论所需资源全部会走 HTTPS 了。由于多说代码会更新,本文具有一定的时效性,大家可以参考我的做法自行修改,不要照搬代码。

最后,我在迁移 Disqus 到多说的过程中,参考了以下两篇文章,在此表示感谢:

  • Disqus 和多说在 Jekyll 的恩怨情仇
  • 让多说评论框完美支持HTTPS

本文链接: https://imququ.com/post/duoshuo-and-https.html

-- EOF --

2015-09-27 12:46:09 发表于「前端技术」分类下。

本站部署于「 阿里云 ECS 」。如果你也要购买阿里云服务,可以使用我的九折推荐码 NY1Z0E ,感谢你对本站的支持!

正文到此结束
Loading...