gitea
This commit is contained in:
71
frontend/app/api/proxy/route.ts
Normal file
71
frontend/app/api/proxy/route.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
const { searchParams } = new URL(request.url)
|
||||
const targetUrl = searchParams.get('url')
|
||||
|
||||
if (!targetUrl) {
|
||||
return NextResponse.json({ error: 'URL parameter required' }, { status: 400 })
|
||||
}
|
||||
|
||||
try {
|
||||
// Validate URL
|
||||
const url = new URL(targetUrl)
|
||||
|
||||
// Only allow http/https
|
||||
if (!['http:', 'https:'].includes(url.protocol)) {
|
||||
return NextResponse.json({ error: 'Invalid URL protocol' }, { status: 400 })
|
||||
}
|
||||
|
||||
// Fetch the page
|
||||
const response = await fetch(targetUrl, {
|
||||
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': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
||||
'Accept-Language': 'en-US,en;q=0.5',
|
||||
},
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
return NextResponse.json(
|
||||
{ error: `Failed to fetch: ${response.status}` },
|
||||
{ status: response.status }
|
||||
)
|
||||
}
|
||||
|
||||
let html = await response.text()
|
||||
|
||||
// Inject base tag to fix relative URLs
|
||||
const baseTag = `<base href="${url.origin}${url.pathname.substring(0, url.pathname.lastIndexOf('/') + 1)}">`
|
||||
html = html.replace(/<head([^>]*)>/i, `<head$1>${baseTag}`)
|
||||
|
||||
// Disable all scripts for security
|
||||
html = html.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
|
||||
|
||||
// Remove event handlers
|
||||
html = html.replace(/\son\w+="[^"]*"/gi, '')
|
||||
html = html.replace(/\son\w+='[^']*'/gi, '')
|
||||
|
||||
// Add visual selector helper styles
|
||||
const helperStyles = `
|
||||
<style>
|
||||
* { cursor: crosshair !important; }
|
||||
a { pointer-events: none; }
|
||||
</style>
|
||||
`
|
||||
html = html.replace('</head>', `${helperStyles}</head>`)
|
||||
|
||||
return new NextResponse(html, {
|
||||
headers: {
|
||||
'Content-Type': 'text/html; charset=utf-8',
|
||||
'X-Frame-Options': 'SAMEORIGIN',
|
||||
},
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('[Proxy] Error fetching URL:', error)
|
||||
return NextResponse.json(
|
||||
{ error: error instanceof Error ? error.message : 'Failed to fetch URL' },
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user