Hao 博客音乐 API 自建与深度排错全记录
AI-摘要
Tianli GPT
AI初始化中...
介绍自己
生成本文简介
推荐相关文章
前往主页
前往tianli博客
Hao 博客自带的音乐 API 服务早已停摆,播放器加载不出歌曲。这篇文章完整记录了从放弃 Vercel 方案、改用国内云服务器,到用 Docker 部署 Meting API、Nginx 反向代理绑定域名,再到修复浏览器混合内容拦截的全过程与踩坑细节。
目录
- 第一章:背景与起因
- 第二章:初期尝试(Vercel)与放弃
- 第三章:宝塔 + Docker 部署实战(核心)
- 第四章:绑定域名与反向代理
- 第五章:混合内容(Mixed Content)拦截
- 第六章:总结与避坑建议
📌 第一章:背景与起因
- 起因:Hao 博客默认的音乐 API
api.i-meto.com已停止服务,导致博客播放器无法加载音乐。 - 目标:自建一个部署在国内、稳定支持 HTTPS、不受版权 IP 限制的专属 Meting API。
- 环境准备:阿里云 ECS 服务器、宝塔 Linux 面板、FinalShell 终端连接工具。
🚧 第二章:初期尝试(Vercel)与放弃
- 尝试方案:在 GitHub 上 Fork 了
chuyegzs/Meting-UI-API并导入 Vercel 部署。 - 踩坑记录:
- 网络阻断:Vercel 默认分配的
*.vercel.app域名在国内被 DNS 污染,无法访问,必须绑定自定义域名。 - IP 限制:即使把 Vercel 的函数区域改到香港(
hkg1),但节点依然在海外,请求 QQ 音乐等国内版权严格的音源时,无法获取真实音频地址和歌词。
- 网络阻断:Vercel 默认分配的
- 最终结论:放弃 Vercel,拥抱国内云服务器。
🐳 第三章:宝塔 + Docker 部署实战(核心)
3.1 解决 Docker 拉取镜像超时
- 报错:
docker: Error response from daemon: Get "https://registry-1.docker.io/v2/": context deadline exceeded... - 原因:国内服务器直接连接 Docker 官方仓库极慢,且阿里云旧版加速器已失效。
- 测试失败的源:
docker.xuanyuan.me(提示免费节点繁忙)docker.m.daocloud.io(提示不在白名单)docker.1ms.run(下载到一半卡在 Waiting)
- ✅ 最终成功方案:使用
dockerproxy.net代理源直接拉取。
docker pull dockerproxy.net/intemd/meting-api:latest
3.2 给镜像打标签并启动容器
- 打标签:因为是从代理源拉的,必须重命名让 Docker 识别。
docker tag dockerproxy.net/intemd/meting-api:latest intemd/meting-api:latest
- 启动容器:映射宿主机
25000端口到容器内部的3000端口。
docker run -d --name meting -p 25000:3000 intemd/meting-api:latest
- 验证:执行
docker ps,看到状态为Up,且端口映射为0.0.0.0:25000->3000/tcp即成功。
3.3 清理与防坑提示
- 如果在下载中断或重试后想清理垃圾,可以使用
docker system prune。 - ⚠️ 避坑:千万不要随意执行
docker image prune -a -f,这会把还没启动的镜像当成垃圾直接删掉,导致前功尽弃。
3.4 穿透防火墙(极其容易被忽略)
- 宝塔放行:宝塔面板 → 安全 → 放行 TCP
25000端口。 - 阿里云放行:阿里云控制台 → 安全组 → 入方向 → 手动添加 TCP
25000端口(授权对象0.0.0.0/0)。这是必做步骤,否则外网绝对打不开。
🌐 第四章:绑定域名与反向代理
- 添加站点:在宝塔面板新建站点
api-meting-music.jikai666.top。 - 反向代理:在该站点的设置中,添加反向代理,目标 URL 指向
http://127.0.0.1:25000。 - 申请 SSL:在 SSL 选项卡中,使用 Let's Encrypt 申请免费证书,并开启右上角的"强制 HTTPS"。
- 此时,浏览器访问
https://api-meting-music.jikai666.top/能看到 API 的测试主页。
💥 第五章:终极难题 —— 混合内容(Mixed Content)拦截
5.1 现象与报错
- 博客本身是
https://,但播放器无法播放、歌词不显示。 - 按
F12查看控制台,出现红字报错:Mixed Content: The page at 'https://halo.jikai666.top/' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://api-meting-music.jikai666.top/api?...' - 原因:后端的 Meting API 在生成歌词或音频链接时,写死了
http://协议。浏览器为了安全,直接拦截了这种请求。
5.2 走过的弯路(失败的尝试)
- 前端 JS 覆盖变量:在 Halo 后台注入
window.meting_api = 'https://...',无效。因为前端插件内部写死了逻辑。 - 前端拦截 Fetch/XHR:注入代码拦截并替换
http://为https://,无效。因为拦截代码没跑过播放器底层的加载逻辑。 - 更换插件:安装官方 APlayer 插件,依然被拦截。
- 传递协议头:在 Nginx 反代中加入
proxy_set_header X-Forwarded-Proto $scheme;,后端顽固不化,依然返回http://。
5.3 🎯 终极必杀技:Nginx sub_filter 暴力替换
既然后端不听话,我们就在 Nginx 这一层,把后端返回给浏览器的所有 http:// 强行替换成 https://。
⚠️ 为什么之前的替换失败?
因为 Nginx 默认开启了 gzip 压缩。数据传回来是乱码,sub_filter 找不到 http:// 文本。
✅ 完整且生效的 Nginx 配置(位于宝塔反代文件中):
#PROXY-START/
location ^~ /
{
proxy_pass http://127.0.0.1:25000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
# 1. 告诉后端这是 HTTPS 访问(虽然它不认,但按规范加上)
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port 443;
# 2. 👇 核心大招:强制解压、强制替换、覆盖所有文件类型 👇
gzip off; # 必须关闭压缩,否则无法查找文本
proxy_set_header Accept-Encoding "";
sub_filter_types *; # 搜索所有内容类型(包含 JSON 接口数据)
sub_filter 'http://api-meting-music.jikai666.top' 'https://api-meting-music.jikai666.top'; # 替换规则
sub_filter_once off; # 替换所有匹配项,不要只替换第一个
# 👆 核心大招结束 👆
add_header X-Cache $upstream_cache_status;
set $static_filezgowjLzS 0;
if ( $uri ~* "\.(gif|png|jpg|css|js|woff|woff2)$" )
{
set $static_filezgowjLzS 1;
expires 1m;
}
if ( $static_filezgowjLzS = 0 )
{
add_header Cache-Control no-cache;
}
}
#PROXY-END/
5.4 验证结果
重启 Nginx 后,测试页面 https://api-meting-music.jikai666.top/test 里的所有请求成功变绿(https://),博客前端无需任何修改,音乐与歌词完美播放。
💡 第六章:总结与避坑建议
- 国内建站首选国内服务器:QQ 音乐、网易云等接口对海外 IP 极其敏感,Vercel 等海外平台不适合做国内音乐解析。
- 端口放行双管齐下:宝塔放行了,必须去阿里云/腾讯云控制台的"安全组"再次放行。
- Nginx 协议替换必杀技:以后遇到任何"HTTPS 页面请求 HTTP 资源"被拦截的问题,记住三板斧:
gzip off;proxy_set_header Accept-Encoding "";sub_filter+sub_filter_types *;
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 WaNG
评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果