每天学一点

每天学一点

AI、Web技术、读书笔记

使weinre支持https

在远程调试手机网页的工具中,weinre算是元老级的了,但是作为一个独立工具已经很久没有更新(现在成了Cordova的一个子项目),易用性落后于Chrome内置的调试工具,也比不上微信web开发者工具。 但是纯粹在“远程”这一点上,还是无可替代的,不需要连接USB,不需要在同一个局域网,weinre可以调试任何一台连接到你服务器的手机。 weinre通过将一个JavaScript文件引入目标网页达到远程调试的目的,但是在https加密的网站上,会遇到浏览器
1 min read

SSE 与 LiveReload

之前实现了自己的编译工具 dev.js ,用了快三个月,感觉良好,可以彻底把 gulp 甩掉了。不过上次也留下一个小尾巴,整合自动重载功能。 最初的打算是用 live.js 这个方案,因为无需改动自己的代码,只要把 live.js 加载到网页中就可以。不过实际用起来,发现还是有点问题。live.js 本身功能是正常的,但其机制是轮询,会在 network 里留下很多请求记录,调试时看起来很乱。 备选方案考虑了 WebSocket ,不过看起来不如 SSE 简单,如果想要用起来简单,就得上 socket.io 这样的库。不过既然 sse 已经够用,省下一个库自然更好。 SSE SSE 的全称是 Server-sent events,也就是服务器推送事件,SSE
4 min read
Nginx

Simple NginScript

某客户有定时关闭网站的需求,每天晚上10点后关闭,第二天6点开启,节假日全天关闭。 想到通过 nginx 的配置文件实现,但是自己对 nginx 的掌握一直停留在“够用”阶段,涉及逻辑判断的功能从来没用过,只是知道 nginx 一定具备这样的功能。 网上一搜,马上发现一篇关于通过 lua 控制服务器开关的文章,与我的需求非常类似,只是其基于 lua 模块,而我服务器上用的是官方源,不带 lua 模块,而且跑了好多个网站,自己编译或者换用 openresty 有一定风险搞挂掉,慎重起见又是一番搜索,决定用 nginScript 来实现这个功能。 安装 如果你像我一样用了 nginx 的官方源,安装就比较简单了,nginx 官方以动态库的形式提供了 nginScript 模块,在 CentOS 中只要执行 yum install
4 min read
Node.JS

dev.js

写完这篇关于 npm scripts 的博客后,我又陆续花了两个半天,将这个定制脚本做到了能让自己满意的程度。功能和性能全面超越了原来的 gulp 脚本,投入的时间也很合理,因为之前无论 gulp 还是 webpack ,都至少花掉我一天时间用在配置上,却达不到理想的效果。 从功能上看,现在的脚本能监视目录、优化代码(主要痛点,市面上没有现成的方案)、检查代码、编译 riot 标签、打包文件,并为自动重载做好了准备。从性能上看,由于充分利用了内存来加速,每次文件变更后触发的流程(优化、检查、编译和打包)提速在十倍以上,从原来的平均超过 1000 ms 到现在的平均不到 100 ms。只是启动仍然需要 2 秒左右,但也比原来稍胜一筹,加上优化难度大、提升空间有限,且一般而言一天也就执行一次,就不强求了。 当前版本的完整代码如下: // 依赖引入
7 min read
前端

用 Prettier 处理 Pug 文件

Prettier 是一个新兴的代码格式化程序,但目前支持的语言相对有限,特别对于混合文件的处理仍在比较初级的阶段。 因此,针对 Riot 这种 HTML/Pug 中混合了 JavaScript 和 CSS 的文件,要对其中的代码进行格式化,必须先将文件分解,分别用 Prettier 处理后,再重新合并。 相比 HTML,处理 Pug 这种由缩进决定包含关系的文件倒是更简单,很容易通过一些简单粗暴的方法进行分解。 Prettier 本身也是一种广受欢迎的粗暴解决方案。它的主要动机就是通过将一种固定格式强加给代码,消灭不同风格间的优劣之辫,节约程序员在争辩中浪费的时间,集中精力办实事。因为大多数时候,主流风格间并没有明显的好坏,只是个人喜好不同。 文件分解 const split = (tag) => { var pug, script, style; [pug, script] = tag.split(/\n
3 min read
Featured

人生小事——我的故事

快过年了,才突然发现,即将过去的一年是个有趣的年份:工作八年,学编程十六年,虚岁三十二。前者各占后者一半。 人生充满了巧合。 都说“人生大事”,回忆往昔,对我有重大影响的,却偏偏是一些小事。 在这个寒冷的冬夜,躲在被窝里码字,给大家讲讲——我的故事。 初中时的一个夜晚,在自习课的间隙,沈达超拿着文曲星跑来给我看,“你看,能画圆,画方”,他把程序给我演示了一下。我一直记得他高兴和兴奋的模样,却想不起来自己当时的感受。有一点很明确,这大概是我见过最神奇的东西了。 几分钟的时间,却影响了我的人生,现在回想起来也很奇妙,他为什么要来给我看这个呢…… 也许是因为之前上过一学期的电脑课,其中有一节课,老师让我们用一个叫 QBASIC 的软件,做了一些奇怪的事。老师给我们一张纸,上面有一些字,让我们照着输进去,内容我还记得一部分,其中一段大概是这样: 10 A = 4 20 PRINT A 30
3 min read
编程熟手入门Go语言
图书

编程熟手入门Go语言

2018年看完的第一本书,《Introducing Go》是一本介绍 Go 语言的书,针对人群是已经有编程经验的读者。全书,算上封面、目录、附录、索引,总共才 124 页,实际阅读时间(包括手打一遍示例代码并完成每章后面的习题),不到15个小时。我是一次一小时左右断断续续看完的,但是需要的话,完全可以在一个周末看完。 总体评价是短小精悍,有编程经验的读者入门 Go 语言的理想书籍。
7 min read
Node.JS

Npm Scripts

代码两周前就完成了,但是上周工作忙,这周又小小沉迷了泰拉瑞亚,现在才来进行总结。 这次主要讲讲返璞归真,用 npm 取代 Gulp 对前端项目进行一些处理。 这篇文章涉及内容过多,似乎应该拆成多个主题 原由 当我刚学着用 Gulp 的时候,就搜过一些文章,看看它有什么优缺点,那时 Gulp 正热,大有取代 Grunt 的趋势。在搜索的过程中,也看到了几篇文章,主旨是使用 npm 来取代 Gulp 和 Grunt,那些文章绝非彼时主流,虽然似乎也有些道理,却没有抓到我的痛点。毕竟用 Gulp 的插件还是比自己从头写方便。 转眼快三年了,Prettier 的出现打乱了我平静的生活~笑~。一个梦寐以求的功能出现在我的面前—— Prettier 的功能是对代码进行格式化,所有人写的代码都会被统一成相同的风格,相较我正在使用的“eslint检查后手动修改”的方案,更加彻底。
4 min read
Npm Scripts

Npm Scripts

代码两周前就完成了,但是上周工作忙,这周又小小沉迷了泰拉瑞亚,现在才来进行总结。 这次主要讲讲返璞归真,用 npm 取代 Gulp 对前端项目进行一些处理。 这篇文章涉及内容过多,似乎应该拆成多个主题 原由 当我刚学着用 Gulp 的时候,就搜过一些文章,看看它有什么优缺点,那时 Gulp 正热,大有取代 Grunt 的趋势。在搜索的过程中,也看到了几篇文章,主旨是使用 npm 来取代 Gulp 和 Grunt,那些文章绝非彼时主流,虽然似乎也有些道理,却没有抓到我的痛点。毕竟用 Gulp 的插件还是比自己从头写方便。 转眼快三年了,Prettier 的出现打乱了我平静的生活~笑~。一个梦寐以求的功能出现在我的面前—— Prettier 的功能是对代码进行格式化,所有人写的代码都会被统一成相同的风格,相较我正在使用的“eslint检查后手动修改”的方案,更加彻底。
4 min read
加密货币
区块链

加密货币

很久以前就知道加密货币这回事,但一直停留在听闻的阶段,虽然也从技术角度对其基本原理进行了了解,但从没真正尝试通过挖矿或购买去拥有一枚。 但是最近加密货币实在太火了,开车听个广播也都是相关的新闻,以至于你根本没办法不去注意它。所以,上个周末,我尝试着进一步了解了一下,发现围绕着加密货币,已经产生了一系列有意思的新事物和商业模式,无论加密货币是不是泡沫,这些商业模式却有真实的参考价值。 加密货币有许多种,我选了最具娱乐性的一种 dogecoin ,音译“多吉币”,直译“狗币”。在一定程度上也是受了我某个天天发狗图,用狗头像的亲戚的影响。 介绍加密货币的文章已经很多了,所以对货币本身我只是简单介绍一下,着重介绍加密货币的各种用途和相关的商业模式。你也可以直接跳到网页挖矿那节开始看,有意思的从那里开始。 钱包 每个人都可以拥有一个或多个钱包地址,就像银行账户,只要安装一个钱包软件,就可以得到一个余额为 0 的账户,其他人向这个地址汇款,钱就是你的了。你也可以向别人的地址汇钱,钱会从你的钱包扣除。 加密货币没有中央银行这样的机构,也就没有一个像现实世界中的银行一样的组织
10 min read
阅读

2017读书总结

2017年比较完整的看了二十几本书。 其他看得不深入或看不下去的没有放到这个列表中。 下面的归类和评述纯属个人观点。 标杆 * 《如何阅读一本书》 * 《SQL反模式》 * 《中国哲学简史》 * 《极简欧洲史》 * 《斯坦福极简经济学》 * 《Drawing for the Absolute Beginner》 * 《别让猴子跳回背上》 个人认为这些书在各自领域已经到达一定高度,短时间内不会出现能与之匹敌者。 如何阅读一本书 以阅读的四个层次为序,教你如何阅读一本书。先从略读开始,初步判断书的类别并决定是否有必要继续深入阅读;再到具体理解、分析和评价一本书,并针对各类书籍特点给出相应建议;最后介绍主题阅读——如何就同一主题,相互参照着同时阅读多本书,并从中总结有用的观点和信息。 个人认为,所有观点中最核心的
13 min read

聚沙成塔

今天初步把以前的博客从时光机搬了回来。勉强能用RSS文件导回一些,更多是靠手动搬运,部分文章的排版仍是混乱的,有空再慢慢整理吧。 没有这些博客,我都忘记自己是怎么过来的了,早期的文章记录的都是些细碎的东西,解决的都是一个个非常具体的问题。虽然,好多解决方法现在看来都不完善,同样的问题其实也可能是其他原因导致的,那时却根本无法看到,只知道某个方法奏效了,那就记录下来。 因为简单,产量就很高,最多的时候半个月能写5篇,简直难以想象。光光解决各种乱码问题就能写上3篇,毕竟,写第一篇的时候想不到还会需要另两种方法来解决一个看似相同的问题。 但正是这些细小的沙子慢慢往上垒,我今天才有机会从更高的视角来俯视曾经的稚嫩吧。
1 min read

归来的技术栈——无状态的服务端

本系列文章都是以方便开发和维护为出发点,在可能的时候,尽量兼顾性能方面的需求 本文是 归来的技术栈 的第三篇,必要时请阅读链接中的内容了解背景。 如果拿 Node.js 和 PHP 比较,我向来是喜欢 Node 多一点。但有一点是 PHP 天然具备, 而 Node 需要付出一些努力才能实现的。 默认情况下,PHP 针对每个请求会使用独立的进程来处理,完成后即销毁。虽然从性能上来说,每次执行都要重复加载文件和数据会带来负面影响,但在另一些方面,却有着先天优势。 比如某个请求发生了错误,不会对另一个请求造成影响;内存泄漏的负面效果无法累积起来影响系统的长期稳定运行;在一定程度上只要堆服务器就可以横向扩展来提高并发能力;不需要针对服务器启停编写额外的代码来初始化和扫尾;服务器意外关闭一般也不会造成什么影响(虽然也不总是如此,比如用了APC之类)。 这些都是无状态带来的好处,可以降低开发和维护的成本,并通过堆硬件提高性能。抛弃一些东西,在其他方面就可以获得更多。 完全无状态的服务端类似一个巨大的纯函数,每个参数相同的请求都会获得相同的结果,也不对外部环境产生影响。但是如
4 min read
归来的技术栈

归来的技术栈——无状态的服务端

本系列文章都是以方便开发和维护为出发点,在可能的时候,尽量兼顾性能方面的需求 本文是 归来的技术栈 的第三篇,必要时请阅读链接中的内容了解背景。 如果拿 Node.js 和 PHP 比较,我向来是喜欢 Node 多一点。但有一点是 PHP 天然具备, 而 Node 需要付出一些努力才能实现的。 默认情况下,PHP 针对每个请求会使用独立的进程来处理,完成后即销毁。虽然从性能上来说,每次执行都要重复加载文件和数据会带来负面影响,但在另一些方面,却有着先天优势。 比如某个请求发生了错误,不会对另一个请求造成影响;内存泄漏的负面效果无法累积起来影响系统的长期稳定运行;在一定程度上只要堆服务器就可以横向扩展来提高并发能力;不需要针对服务器启停编写额外的代码来初始化和扫尾;服务器意外关闭一般也不会造成什么影响(虽然也不总是如此,比如用了APC之类)。 这些都是无状态带来的好处,可以降低开发和维护的成本,并通过堆硬件提高性能。抛弃一些东西,在其他方面就可以获得更多。 完全无状态的服务端类似一个巨大的纯函数,每个参数相同的请求都会获得相同的结果,也不对外部环境产生影响。但是如
4 min read
Node.JS

归来的技术栈——正确模块化,express 的 app.use

在 express 4 中,app.use 有如下用法: const express = require('express'); const app = express(); const subapp = express(); app.use('/subpath', subapp); app.listen(3000); subapp 做为 express 的一个实例,本身也是 middleware ,可以被 app.use “挂载”到指定路径。 这种用法给我们项目中功能模块的可移植性进一步增加了保证,以之前用到的目录结构为例: . ├── app.js └── src ├── admin │ ├── stylesheets │ ├── javascripts │ ├── index.html │ ├── client.
1 min read
SVG

Svg Filter 相关的几个问题

在用 Leaflet 处理 GeoJSON 格式的地理信息时,解析结果被以内联的 SVG 格式嵌入网页中。为了使地图更有质感,希望通过添加阴影获得视觉上的高低效果,尝试过程记录如下。 css 首先,<svg> 内的元素是支持 css 样式的,用法也和普通的 css 一样,可以通过 id 或 class 来套用样式,但是 svg 元素具体支持的规则和普通 DOM 元素相差很大 box-shadow box-shadow 不支持 svg 内部的元素 filter filter 的 drop-shadow 也可以制造阴影效果,但是目前只有 Edge 支持对 svg 内部元素使用 元素 <defs&
3 min read
感悟

大规模数据上传的问题和解决

过完年第一天上班,就接到一个项目连夜出差去了。客户手头有大约 20 万条住房信息需要上报到一个指定的系统。这 20 万条记录由 200 多个员工花了超过一个月的时间到该县辖区内的各自然村挨家挨户上门采集,然后以乡镇-行政村-自然村的结构存放在 1000 多个 excel 文件中。excel 中的每条记录对应一套住房,同目录下,还有房屋的照片。 这些信息和图片都要上传到一个指定的网站,当然,没有接口。 所以,问题还是很清晰的,就是实现一个爬虫模拟请求,先登录网站,然后从 excel 中依次读取记录,将相应的信息和图片进行上传,重复这个过程。 常规问题 技术选择 其实没什么好选,我最熟悉的语言是 PHP 和 JavaScript,最终选了 Node.js 。平常处理网络请求已经用的很多,处理数据的话有 underscore ,模拟请求有 superagent ,处理 dom 内容有 cheerio
6 min read
前端

用加载画面改善用户体验

毋庸置疑,单页面应用(Single Page Application,以下简称 SPA)正在变得越来越流行。SPA 具有前后端分离、接口重用度高、操作响应快速等优点,在用户体验上相比传统的网站也更接近原生应用。但与此同时,SPA 的体积却在不断增大,导致加载所需的时间越来越长,而这个问题在微信里面特别突出。 微信中的加载问题 首先,微信通常安装在移动设备上,网络的速度并不像固定宽带那么有保障,虽然 4G 已经普及,但总有些地方或某些时候网络没那么理想。在网络状况不佳时,加载较大的 SPA 耗时较长,屏幕表现为长时间白屏。 然后,微信对网页的缓存机制跟一般的浏览器不同。即使你没在服务器上进行特别的配置,它默认就会缓存 html、css、javascript 等它认为是“静态”的内容,而且在缓存有效期间“拒绝”去服务器上看看是否有更新,给不少新接触微信开发的程序员造成困扰。反过来,当你希望它将某个内容长期缓存,并通过响应头部的信息明确告知时,它也不能很好的遵守。说实话,
10 min read
CentOS 6

在 CentOS 6 和 Nginx 中部署 Let's Encrypt 的 SSL 证书

上周写了一篇文章讲了讲为什么应该使用 HTTPS 加密你的网站,并笼统的介绍了如何申请和使用 Let's Encrypt 提供的 SSL 证书。这次我们说说如何在 CentOS 6 和 Nginx 中部署 Let's Encrypt 的 SSL 证书,过程中可能遇到的问题,以及如何解决。 整体上分成申请证书和使用证书两个部分。 申请证书 准备工作 在申请证书之前,你必须有一个域名,并配置好 DNS 解析服务,使其指向你将要使用的服务器。说白了,就是你要保证所有人都可以通过在浏览器中输入域名打开你的网站。 此时 Nginx 的配置文件如下(为了便于说明只包含了最基本的信息): [ngxin] server { listen 80; server_name www.bnlt.org;
7 min read

把你的网站升级到 HTTPS

作为一个普通用户,在使用手机浏览网页,或是阅读微信中别人分享的内容时,经常会看到屏幕下方有个弹出广告,什么点击领红包啦,免费送流量啦,或是移动运营商的广告。通常这些广告跟你浏览的网站本身风格完全不搭、画质又非常糟糕、而且在几个毫不相干的网站中都出现了。遇到这样的情况,基本可以肯定是有中间人劫持了你的流量,并篡改了网页内容,在其中嵌入了广告。纯粹做做广告已经算是客气,更恶劣的可以替换你浏览的网页内容,把你引向钓鱼网站,甚至直接窃取你的密码。 作为一个开发者,你的境遇更糟糕,因为这一切时刻都发生在你自己的网站或 APP 上。也许是你花费不少心思才做出来的精美页面被一个很粗糙的广告拉低了好几个档次;也许是一个重要活动的报名按钮被广告遮挡,你的用户不得不先小心翼翼关了广告才能继续;也许是为一个大客户制作的严肃的内容下面出现了一段夸张又搞笑的广告语。 但最最糟糕的是,你的大多数客户和用户都不清楚这是运营商或广告商劫持了他们的流量,而是以为你这个家伙为了一点微薄的广告收入在里面嵌了品味低下的广告,毕竟这网站是你的,这应用是你开发的,不是你干的还能是谁呢。你是希望当这一切发生的时候向他们解释
5 min read
用ImageMagick将PDF转换成多张图片
ImageMagick

用ImageMagick将PDF转换成多张图片

今天遇到一个需求,客户发来几份PDF,想放到他们的微网站(专门给微信用的网站)上,由于是给手机看的,加上文件页数不多,就想到转换成图片再放上去。 第一时间想到用 ImageMagick 的 convert 命令,网上一搜,命令如下: convert -density 600 foo.pdf foo-%02d.jpg -density 设置了生成的图片的精度,数值越大,图片越清晰(分辨率高),转换也越慢。如果给手机用,普通 A4 大小的 PDF 设置在 200 左右比较合适。 foo-%02d.jpg 是希望生成的文件名,%02d 部分会替换成页码(从 0 开始),用过 printf 函数的应该对这个规则会比较熟悉。 然而在实际使用时遇到了一个意外情况:
1 min read
前端

Hash, PushState 和微信 JSSDK 授权

最近将 riot.js 升级到了 3.0,并用上了新版本的 riot-route,原先用了一年多的 2.2.4 版本内置的 riot.route 只支持 hash 形式的 SPA 单页面应用,riot-route 则支持 pushState。 Hash 方式有个缺点,就是服务器不知道地址栏中 # 之后的内容,放在微信里,就导致了未授权用户授权后想返回原界面需要借助 JS 来实现,导致历史记录多了一条,用户按返回键无法退出(返回上一页面后又被 JS “前进”了)。 PushState 方式就没有这个问题,可以直接用 HTTP 302 重定向过来,不影响历史记录和返回按钮功能。 于是在新项目中开始采用 pushState 方式。 不过等到应用到了微信环境中,又冒出来一个问题,通过
4 min read
浙ICP备15043004号-1