feat: iframe proxy test — fetch Sechenov page, strip X-Frame, rewrite URLs
This commit is contained in:
40
server.js
40
server.js
@@ -137,4 +137,44 @@ app.post('/api/chat', async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
// ── iframe proxy: fetch student.sechenov.ru, strip X-Frame-Options, rewrite URLs ──
|
||||
app.get('/proxy/*', async (req, res) => {
|
||||
const upstreamPath = req.url.replace(/^\/proxy/, '') || '/';
|
||||
const upstreamUrl = 'https://student.sechenov.ru' + upstreamPath;
|
||||
|
||||
try {
|
||||
const r = await fetch(upstreamUrl, {
|
||||
headers: {
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
||||
'Accept': req.headers.accept || '*/*',
|
||||
'Accept-Language': req.headers['accept-language'] || 'ru,en;q=0.9',
|
||||
},
|
||||
});
|
||||
|
||||
const ct = r.headers.get('content-type') || 'application/octet-stream';
|
||||
res.status(r.status);
|
||||
res.setHeader('Content-Type', ct);
|
||||
// strip framing restrictions
|
||||
res.removeHeader('X-Frame-Options');
|
||||
res.removeHeader('Content-Security-Policy');
|
||||
|
||||
if (ct.includes('text/html')) {
|
||||
let html = await r.text();
|
||||
// rewrite relative URLs to absolute so browser loads assets directly
|
||||
html = html
|
||||
.replace(/(href|src|action)="\/(?!\/)/g, '$1="https://student.sechenov.ru/')
|
||||
.replace(/url\(["']?\/(?!\/)/g, 'url(https://student.sechenov.ru/')
|
||||
// neutralize meta CSP if present
|
||||
.replace(/<meta[^>]+http-equiv=["']?Content-Security-Policy["']?[^>]*>/gi, '');
|
||||
res.send(html);
|
||||
} else {
|
||||
// stream binary/text as-is
|
||||
const buf = Buffer.from(await r.arrayBuffer());
|
||||
res.send(buf);
|
||||
}
|
||||
} catch (e) {
|
||||
res.status(502).send('proxy error: ' + e.message);
|
||||
}
|
||||
});
|
||||
|
||||
app.listen(8108, () => console.log('sechenov :8108'));
|
||||
|
||||
Reference in New Issue
Block a user