语初AI
YCGPT
暂无摘要
子比主题 Steam 游戏库插件支持拉取 Steam 个人游戏清单,展示游戏卡片、总游玩时长、游戏统计数据
![图片[1]-子比主题 - Steam游戏库插件-语初博客](https://p0.ssl.qhimg.com/t111922529dd6b8bbb1c32ce58a.webp)
![图片[2]-子比主题 - Steam游戏库插件-语初博客](https://p0.ssl.qhimg.com/t111922529d1369f9335ecd2cda.webp)
![图片[3]-子比主题 - Steam游戏库插件-语初博客](https://p0.ssl.qhimg.com/t111922529dbd3d9358f787a9c6.webp)
![图片[4]-子比主题 - Steam游戏库插件-语初博客](https://p0.ssl.qhimg.com/t111922529d02d16568979c211d.webp)
![图片[5]-子比主题 - Steam游戏库插件-语初博客](https://p0.ssl.qhimg.com/t111922529d27d46abf2e4f1ca5.webp)
Worker 代码
/**
* Steam API 反向代理 — Cloudflare Worker 自建模板
*
* 路由:
* /ISteamUser/...、/IPlayerService/... → api.steampowered.com(Web API)
* /store/api/appdetails?... → store.steampowered.com(游戏简体中文名)
*
* 部署步骤:
* 1. Cloudflare Dashboard → Workers 和 Pages → 创建 Worker(名称随意)
* 2. 将本文件全部代码粘贴进编辑器并部署,得到地址 https://xxx.xxx.workers.dev
* 3.(推荐)Worker → 设置 → 变量和机密 → 添加「文本」变量:
* 变量名 SECRET,值为一串随机字符(如 openssl rand -hex 16 生成)
* 也可以直接写在下方 SECRET 常量里,二选一
* 4. 插件后台「Steam游戏库 → 接口配置」:
* API 反代地址 填 https://xxx.xxx.workers.dev
* Worker 鉴权密钥 填与 SECRET 相同的值
*
* 说明:Workers 免费版每天 10 万次请求。本插件在 WordPress 侧已做本地缓存,
* 玩家资料 4 个接口 + 商店中文名补全,个人博客流量绰绰有余。
* 商店 appdetails 已在 CF 边缘缓存 1 小时,重复请求不回源。
*/
//鉴权密钥:为空则不校验(不推荐公开使用);环境变量 SECRET 优先
const SECRET = '';
const AUTH_HEADER = 'x-steam-proxy-auth';
const API_ORIGIN = 'https://api.steampowered.com';
const STORE_ORIGIN = 'https://store.steampowered.com';
const STORE_PREFIX = '/store/';
export default {
async fetch(request, env) {
const url = new URL(request.url);
const jsonError = (status, msg) =>
new Response(JSON.stringify({ error: msg }), {
status,
headers: { 'content-type': 'application/json; charset=utf-8' },
});
//只开放 Steam 用到的 GET/HEAD,收窄滥用面
if (request.method !== 'GET' && request.method !== 'HEAD') {
return jsonError(405, 'method not allowed');
}
const secret = (env && env.SECRET) || SECRET;
if (secret && request.headers.get(AUTH_HEADER) !== secret) {
return jsonError(403, 'forbidden');
}
//带 /store/ 前缀的转发商店接口,其余原样转发 Web API
const isStore = url.pathname.startsWith(STORE_PREFIX);
const target = isStore
? STORE_ORIGIN + url.pathname.slice(STORE_PREFIX.length - 1) + url.search
: API_ORIGIN + url.pathname + url.search;
const init = {
method: request.method,
headers: {
'user-agent': request.headers.get('user-agent') || 'zibll-steam-proxy/1.0',
'accept-language': 'zh-CN,zh;q=0.9',
},
};
if (isStore) {
init.cf = { cacheTtl: 3600, cacheEverything: true };
}
let upstream;
try {
upstream = await fetch(target, init);
} catch (e) {
return jsonError(502, 'upstream error');
}
const resp = new Response(upstream.body, upstream);
if (!resp.headers.get('content-type')) {
resp.headers.set('content-type', 'application/json; charset=utf-8');
}
return resp;
},
};
© 版权声明
© 版权声明 All Rights Reserved
THE END










![表情[qiang]-语初博客](https://www.yc520.top/wp-content/themes/zibll/img/smilies/qiang.gif)

暂无评论内容