之前用 Python 把学校教务系统的登录直链生成逻辑实现了一下,但毕竟是个命令行程序,极大限制了运行的便利程度。想来如此简单的计算方式,用任何一门语言应该都能很快实现。
自从上次初学 Node.js,搭了个 Webhook 之后,就感觉自己终于有可能不再被拘束于黑漆漆的终端,而可以自己做个前端界面玩玩了。于是着手开始使用 Node.js 写脚本。
链接生成规则详见《NJUST 教务系统免验证码直链登录初探》,这里不再赘述。其关键是计算一个 MD5 值。js 里似乎没有直接计算的函数,需要用别人的轮子。这里我引入了 blueimp/JavaScript-MD5 这个实现方案,可以点击这里直接下载 md5.js,放到我们正在做的 js 脚本同目录下。注意,这个模块的输出是小写的 MD5 值,需要使用 toUpperCase
函数做一个转换。
链接生成核心语句如下:
1 |
|
其中 POST.id
与 POST.pw
都来自用户从 Web 界面提交的表单。
用 HTML 写一个简易(简陋)的表单提交页面很容易。整个服务器的代码参考之前 Webhook 的模式。完整代码如下:
1 |
|
手机上的运行效果如下:
提交之后:
可见,基本功能是实现了。然而尽管特地加入了 <meta name="viewport" content="width=device-width, initial-scale=1.0">
这句响应式布局的门槛,Web 界面还是显得很丑相当简约。
于是,为了做出真正意义上的、我人生的第一个亲手写的、能让人看得下去的网页,我下了很大功夫,研究了一下各种主流的前端框架,终于从入门到放弃了决定这些统统都不用。
最后,我从 OneIndex 的密码输入页面找到了灵感:
完美的响应式布局!简约而舒服的 MD 配色!还有动画效果!
虽然 OneIndex 的网页是用 PHP 生成的,但这并不妨碍我直接扒下它的 HTML 源码。从源码里可以看出,这个网页的 CSS 用的是一个叫做 MDUI 的框架。搜了一下,这个 CSS 框架用于开发 Material Design 网页,比较小众,但好评很多,控件也覆盖得比较丰富。就决定是你了,MDUI!
套 CSS 框架可比用什么三大框架(React、Vue、Angular)、Bootstrap、jQuery 简单多了,无非是开头引入一下 css 和 js:
1 |
|
然后对着开发文档魔改就行了。
最终成果如图:
用 Node.js 输出外部的一个 HTML 文件作为响应也很简单,首先要引入 fs 模块:
1 |
|
然后即可在需要的地方读取文件。如 response 以 jwc.html
结束:
1 |
|
在 Web 界面上填写完学号密码,点击生成后,会打开新的页面展示链接,这个界面就比较简陋了,没有再去做美化,类似刚才的版本。
此外,由于毕竟涉及密码的填写,url 直接用 <ip>:<port>
的形式未免显得太不安全,最好还是希望能够使用域名配合 https 协议。在 Node.js 里搭 https 服务器与 http 的区别在于:
-
开头引入的是 https 模块:
1
let https = require("https");
-
需要添加域名的 SSL 证书和密钥文件:
1
2
3
4const httpsOption = { key: fs.readFileSync("./privkey.pem"), cert: fs.readFileSync("./fullchain.pem") }
我之前申请的是域名通配符证书,所以就直接拿来用了。
-
创建服务器:
1
2
3https.createServer(httpsOption, function (req, res) { //回调函数体 }).listen(httpsPort);
其他与 http 服务器完全一致。
这样做之后只能就只能通过 https 来访问了。要想实现 http 自动跳转到 https 的话,则需要一些其他的手段。
传统的方法是重定向,比如:
1 |
|
然而,我的 url 是 <domain>:<port>
形式的,想要通过 301 做到 http://<domain>:<port>
转 https://<domain>:<port>
显然是不可能的,因为 http 服务器监听的端口肯定是不能与 https 重复的。
《【node】express 请求 http 与 https 一起能访问》 一文提供了一种可行的实现思路。Node.js 中 http 与 https 都是工作于应用层的,可以通过更底层的 TCP 协议来进行控制。
简单来说,就是 http 和 https 分别监听不同的端口,如 http 7401,https 7402;然后引入 net 模块,监听最后真正要访问的那个端口,如 7400,它负责判断请求的是 http 还是 https,然后从各自的端口取数据进行响应(实际是反向代理);https 服务器可以直接执行 301 重定向到 https://<domain>:<port>
。
net 部分的代码如下:
1 |
|
整合一下 http 和 https 服务器的代码,最终完整版代码如下:
1 |
|
这样就能够完美实现 http 与 https 均可访问,且 https 自动跳转 https 啦。
以上所有相关代码(包括 HTML)都可以在我的 repo jasongzy/njust-jwc 里找到。
彩蛋:我选择的服务器访问端口是 7400。EE 专业的可能知道,7400 芯片是四组二入与非门。至于与非门和南理工有什么关系嘛……有 0 出 1,全 1 出 0?