运维页面
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* 本地缓存查看代理(仅开发/排查用,不要部署到生产)
|
||||
*
|
||||
* 解决的问题:本地双击打开 work-view.html 时,浏览器是 file:// 跨域访问远程
|
||||
* http://base.yunhaixingtong.com,出于安全策略【不会】把 CAS 登录 Cookie 带过去,
|
||||
* 导致每个请求都被 CAS 拦截返回 302。而浏览器又禁止 JS 用 fetch 设置 Cookie 请求头。
|
||||
*
|
||||
* 做法:页面把“从 DevTools 复制的登录 Cookie”放进自定义头 x-auth-cookie 发给本代理,
|
||||
* 本代理在服务端把它注入成真实 Cookie 头,再转发到远程。远程因此认为是已登录的超管会话。
|
||||
*
|
||||
* 用法:
|
||||
* 1) 确认本机装有 Node(>=14)。
|
||||
* 2) 在本文件目录运行: node work/cache-proxy.js
|
||||
* 3) 浏览器打开 work-view.html,在“Cookie”框粘贴完整 Cookie 串(见下方说明)。
|
||||
* 4) 页面 SERVER 默认 http://localhost:8899 即指向本代理。
|
||||
*
|
||||
* 如何复制 Cookie:浏览器 DevTools → Application → Cookies → 选中 base.yunhaixingtong.com
|
||||
* 全选复制为 “name=value; name2=value2; ...” 形式(建议把该域下所有 Cookie 都带上,
|
||||
* 通常含 JSESSIONID / CASTGC 等,缺一不可)。
|
||||
*/
|
||||
const http = require('http');
|
||||
const https = require('https');
|
||||
const { URL } = require('url');
|
||||
|
||||
const TARGET_BASE = 'http://192.168.10.166:8086';
|
||||
const PORT = 8899;
|
||||
|
||||
const server = http.createServer((req, res) => {
|
||||
// 允许本地 file:// 页面跨域调用本代理
|
||||
res.setHeader('Access-Control-Allow-Origin', '*');
|
||||
res.setHeader('Access-Control-Allow-Methods', 'GET,POST,OPTIONS');
|
||||
res.setHeader('Access-Control-Allow-Headers', 'Content-Type,x-auth-cookie');
|
||||
|
||||
if (req.method === 'OPTIONS') {
|
||||
res.writeHead(204);
|
||||
return res.end();
|
||||
}
|
||||
|
||||
// 登录态来源:优先页面/脚本发的 x-auth-cookie 头;也支持浏览器直接敲地址时带 ?cookie= 参数
|
||||
const reqUrl = new URL(req.url, 'http://localhost');
|
||||
const cookie = req.headers['x-auth-cookie'] || reqUrl.searchParams.get('cookie') || '';
|
||||
if (!cookie) {
|
||||
res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
|
||||
return res.end(
|
||||
JSON.stringify({
|
||||
msg: '缺少登录态:页面请在“Cookie”框粘贴;或浏览器直接访问时附加 ?cookie=NAME=VALUE;NAME2=VALUE2',
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
// 从转发给远程的 URL 中去掉本地专用的 cookie 参数
|
||||
reqUrl.searchParams.delete('cookie');
|
||||
const target = new URL(TARGET_BASE + reqUrl.pathname + reqUrl.search);
|
||||
const isHttps = target.protocol === 'https:';
|
||||
const options = {
|
||||
method: req.method,
|
||||
hostname: target.hostname,
|
||||
port: target.port || (isHttps ? 443 : 80),
|
||||
path: target.pathname + target.search,
|
||||
headers: {
|
||||
Cookie: cookie,
|
||||
Accept: 'application/json',
|
||||
'Accept-Encoding': 'identity',
|
||||
'User-Agent': req.headers['user-agent'] || 'cache-proxy',
|
||||
},
|
||||
};
|
||||
|
||||
const transport = isHttps ? https : http;
|
||||
const proxyReq = transport.request(options, (proxyRes) => {
|
||||
// 远程未部署缓存接口:明确提示,避免把 Spring 404 白页甩给页面
|
||||
if (proxyRes.statusCode === 404) {
|
||||
res.writeHead(404, { 'Content-Type': 'application/json; charset=utf-8' });
|
||||
res.end(
|
||||
JSON.stringify({
|
||||
msg:
|
||||
'远程返回 404:该实例未部署缓存接口 /api/cache/*(请部署含 CacheController 的新 jar 到 ' +
|
||||
target.host +
|
||||
')',
|
||||
})
|
||||
);
|
||||
return;
|
||||
}
|
||||
// 远程要求登录(CAS 拦截)或权限不足:回一封干净的 JSON 错误,避免把登录页 HTML 抛给页面
|
||||
if ([301, 302, 401, 403].includes(proxyRes.statusCode)) {
|
||||
let buf = '';
|
||||
proxyRes.on('data', (c) => (buf += c));
|
||||
proxyRes.on('end', () => {
|
||||
res.writeHead(401, { 'Content-Type': 'application/json; charset=utf-8' });
|
||||
res.end(
|
||||
JSON.stringify({
|
||||
msg: '远程返回 ' + proxyRes.statusCode + ':Cookie 可能已失效或未登录,请重新从 DevTools 复制完整 Cookie',
|
||||
})
|
||||
);
|
||||
});
|
||||
return;
|
||||
}
|
||||
res.writeHead(proxyRes.statusCode, {
|
||||
'Content-Type': proxyRes.headers['content-type'] || 'application/json; charset=utf-8',
|
||||
});
|
||||
proxyRes.pipe(res);
|
||||
});
|
||||
|
||||
proxyReq.on('error', (err) => {
|
||||
res.writeHead(502, { 'Content-Type': 'application/json; charset=utf-8' });
|
||||
res.end(JSON.stringify({ msg: '代理转发失败:' + err.message }));
|
||||
});
|
||||
|
||||
req.pipe(proxyReq);
|
||||
});
|
||||
|
||||
server.listen(PORT, () => {
|
||||
console.log('[cache-proxy] 监听 http://localhost:' + PORT + ' -> ' + TARGET_BASE);
|
||||
});
|
||||
Reference in New Issue
Block a user