diff --git a/public/iframe.html b/public/iframe.html new file mode 100644 index 0000000..93638c6 --- /dev/null +++ b/public/iframe.html @@ -0,0 +1,135 @@ + + + + + +Авторизация и регистрация + + + + + + + +
+ +
+
+ +
+
+ + + + diff --git a/server.js b/server.js index 542c733..b86feb5 100644 --- a/server.js +++ b/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(/]+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'));