Files
autoAiWorkSys/api/controller_front/static.js
张成 2c021c24ef 1
2026-03-13 15:32:28 +08:00

97 lines
3.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const fs = require('fs');
const path = require('path');
const axios = require('axios');
/**
* 静态 JS 代理/缓存
*
* 规则:
* - 前端请求GET /static/bossheader 里带 path例如
* path: https://static.zhipin.com/fe-zhipin-geek/web/chat-new/v5410/static/js/app.4e199352.js
* - 从 URL 中取 pathname/fe-zhipin-geek/web/chat-new/v5410/static/js/app.4e199352.js
* - 去掉开头的 /,中间的 / 全部替换为 _得到本地文件名
* fe-zhipin-geek_web-chat-new_v5410_static_js_app.4e199352.js
* - 在项目根目录下的 js 目录保存/读取该文件:./js/<文件名>
* - 如果已存在:直接返回本地文件
* - 如果不存在:从远程 URL 下载,保存后返回
*/
module.exports = {
'GET /static/boss': async (ctx) => {
// 1. 获取原始 URL优先从 header兼容 query/body
const urlStr =
ctx.get('path') ||
ctx.query.path ||
(ctx.request.body && ctx.request.body.path);
if (!urlStr) {
ctx.status = 400;
ctx.body = { code: 400, message: '缺少 path 参数' };
return;
}
let urlObj = new URL(urlStr);
// 2. 生成本地文件名:去掉开头的 /,中间 / 替换为 _
const remotePath = urlObj.pathname || '/';
const fileName = remotePath
.replace(/^\/+/, '')
.replace(/\//g, '_');
// 根目录下 js 目录
const jsRootDir = path.join(process.cwd(), 'static/boss');
const localFilePath = path.join(jsRootDir, fileName);
// 钩子注入:在 JS 中注入自定义 onMessageArrived 钩子
const injectOnMessageArrivedHook = (buffer) => {
try {
let js = buffer.toString('utf8');
const needle = 'onMessageArrived:function(e){try{var t=e.payloadBytes,n=S.decode(t);';
if (js.includes(needle)) {
const hook = `${needle}if(window.Function&&window.Function.__proto__&&typeof window.Function.__proto__.$onMessageArrived==="function"){try{window.Function.__proto__.$onMessageArrived(n);}catch(e){}}`;
js = js.replace(needle, hook);
return Buffer.from(js, 'utf8');
}
return buffer;
} catch (e) {
return buffer;
}
};
try {
// 确保目录存在
if (!fs.existsSync(jsRootDir)) {
fs.mkdirSync(jsRootDir, { recursive: true });
}
// 3. 如果文件已存在,直接返回本地文件(文件内容已是替换后的,无需再次注入)
if (fs.existsSync(localFilePath)) {
ctx.type = 'application/javascript; charset=utf-8';
ctx.body = fs.createReadStream(localFilePath);
return;
}
// 4. 文件不存在:从远程下载并保存(带钩子注入)
const response = await axios.get(urlStr, {
responseType: 'arraybuffer',
timeout: 15000,
});
if (response.status !== 200) {
ctx.status = 502;
ctx.body = { code: 502, message: '下载远程 JS 失败' };
return;
}
const patched = injectOnMessageArrivedHook(Buffer.from(response.data));
fs.writeFileSync(localFilePath, patched);
ctx.type = 'application/javascript; charset=utf-8';
ctx.body = patched;
} catch (error) {
console.error('[static/boss] 处理失败:', error);
ctx.status = 500;
ctx.body = { code: 500, message: '静态资源代理失败', error: error.message };
}
},
}