墨水屏天气时钟的现代化改造:从源码到生产部署

💡 起因

翻CSDN的时候看到这篇:Kindle可用的天气时钟,大概就是把吃灰的Kindle拿来当天气时钟用。

说实话博主家里也有几个吃灰设备...

读了下源码,做得还挺完整的——农历、天气、一言都有。不过看着看着就手痒了:这API Key直接写前端里不太行啊,而且每次换个城市还得改HTML…

不如干脆自己动手改一版吧。

🔍 原项目长啥样

简单过一下原项目:

时间日期 农历转换 天气数据 一言名句 天气图标

用的是和风天气API + lunar.js做农历,整体架构就是纯前端。

问题出在哪

翻了翻代码,列几个比较明显的:

问题 怎么回事 严不严重
Key裸奔 API Key明文写在JS里 挺危险
城市写死 想换城市得改HTML 有点麻烦
部署麻烦 没有现成的部署方案 还好

第一个问题最要命——Key放前端,随便谁F12一下就能拿走。虽然和风免费版有调用限制,但还是不太好。

🛠️ 怎么改的

思路其实很简单:把敏感操作挪到服务端

1. 服务端代理

核心改动就是加了个Serverless函数,所有天气请求都走它:

点我看代码~
1
2
3
4
5
6
7
8
9
10
11
12
13
// api/weather.js
export default async function handler(req, res) {
const { type, location } = req.query;

// Key从环境变量读,不暴露给前端
const key = process.env.QWEATHER_KEY;

let url = type === 'city'
? `https://geoapi.qweather.com/v2/city/lookup?location=${location}&key=${key}`
: `https://devapi.qweather.com/v7/weather/now?location=${location}&key=${key}`;

// 代理请求...
}

这样前端只需要请求/api/weather?location=xxx,Key什么的完全接触不到。

2. 自动定位

不想每次都改城市代码,就加了几种定位方式:

默认用这个,不弹窗不授权:

1
2
// 调第三方接口拿IP对应的经纬度
fetchIp("https://uapis.cn/api/v1/network/myip", ...);

精度高,但会弹授权框:

1
navigator.geolocation.getCurrentPosition(...);

配置文件里写死城市ID,适合固定位置用:

1
location: '101210101' // 杭州

3. 拆分代码

原来一个HTML塞所有东西,现在拆开了:

1
2
3
4
5
6
7
├── api/weather.js     # 代理函数
├── js/
│ ├── config.js # 配置
│ ├── app.js # 主逻辑
│ └── loader.js # 加载器
├── css/style.css
└── index.html

4. 支持CDN

静态资源可以走CDN加速:

1
2
3
4
5
assets: {
source: 'npm', // 从npm CDN加载
cdnBase: 'https://cdn.cbd.int',
packageName: 'ink-weather-clock-static'
}

🚀 怎么部署

改完之后部署反而简单了,项目放GitHub上了:

README里有详细的部署文档,这里简单说下流程:

Fork项目

去上面的仓库页面,点右上角Fork到自己账号

导入Vercel

登录Vercel,点 Add New → Project,选刚fork的仓库

配环境变量

在Environment Variables里加上QWEATHER_KEY,填你在和风天气申请的Key

部署

点Deploy,等个一两分钟就行

Vercel免费版完全够用,Serverless函数也支持。更多配置选项(JWT认证、自定义CDN等)看仓库README。

环境变量

变量 干嘛的 必填?
QWEATHER_KEY 和风天气Key 二选一
QWEATHER_JWT_KEY JWT私钥 二选一
WEATHER_LOCATION 默认城市 可选

📸 效果

改造后的效果图
改造后的效果图

🔧 其他配置

JWT认证(可选,更安全)

如果想用JWT而不是API Key:

  1. 这里生成Ed25519密钥对
  2. 公钥传到和风控制台
  3. 私钥和KeyID配到Vercel环境变量里
刷新频率
内容间隔
时间500ms
天气30分钟
一言30分钟

想改的话去app.js里调setTimeout的参数。

📝 最后

改完之后:

Key不暴露了

能自动定位

一键部署

代码清晰点了

家里有吃灰Kindle的可以试试,摆在书桌上当个时钟还挺好看的。

感谢原作者的分享,博主只是在他基础上改了下~