const specialCases = { "*": { "Origin": "DELETE", "Referer": "DELETE" } };
function handleSpecialCases(request) { const url = new URL(request.url); const rules = specialCases[url.hostname] || specialCases["*"]; for (const [key, value] of Object.entries(rules)) { switch (value) { case "KEEP": break; case "DELETE": request.headers.delete(key); break; default: request.headers.set(key, value); break; } } }
async function handleRequest(request) { const url = new URL(request.url); if (url.pathname === "/") { return new Response(`<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>转发服务使用指南</title> <style> body { font-family: Arial, sans-serif; margin: 0; padding: 0; background: #f4f4f4; } .container { width: 80%; margin: auto; overflow: hidden; margin-bottom: 100px; } header { background: #333; color: #fff; padding: 20px; text-align: center; } section { padding: 20px; margin-bottom: 20px; } .example { background: #fff; padding: 20px; border-radius: 4px; margin-bottom: 20px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); } h2 { color: #333; border-bottom: 2px solid #ddd; padding-bottom: 10px; } code { background: #ddd; padding: 2px 6px; border-radius: 4px; display: inline-block; margin: 0 5px; } </style> </head> <body> <header> <h1>转发服务使用指南</h1> </header> <div class="container"> <section> <h2>简介</h2> <p>本服务是一个轻量级的 https 请求转发代理,基于阿里云边缘函数构建。</p> </section> <section> <h2>如何使用</h2> <p>在URL路径中添加目标网址,例如:</p> <div class="example"> <p><strong>示例:</strong></p> <p><code>${url.origin}/https://httpbin.org/get</code></p> <p><code>${url.origin}/https://api.github.com/users/octocat</code></p> </div> </section> <section> <h2>注意事项</h2> <ul> <li>仅支持公开可访问的网站</li> <li>请遵守目标网站的使用条款</li> <li>不要用于非法用途</li> </ul> </section> </div> </body> </html>`, { headers: { 'content-type': 'text/html;charset=UTF-8', }, status: 200 }); } const actualUrlStr = url.pathname.replace("/", "") + url.search + url.hash; // 验证URL格式 let actualUrl; try { actualUrl = new URL(actualUrlStr); } catch (error) { return new Response(JSON.stringify({ error: 'Invalid URL format', message: 'Please provide a valid URL', example: `${url.origin}/https://httpbin.org/get`, provided_url: actualUrlStr }), { status: 400, headers: { 'content-type': 'application/json', 'Access-Control-Allow-Origin': '*' } }); }
// 检查是否为支持的协议 if (!['http:', 'https:'].includes(actualUrl.protocol)) { return new Response(JSON.stringify({ error: 'Unsupported protocol', message: 'Only HTTP and HTTPS protocols are supported', provided_protocol: actualUrl.protocol }), { status: 400, headers: { 'content-type': 'application/json', 'Access-Control-Allow-Origin': '*' } }); } try { // 创建一个新的请求,添加超时控制 const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), 10000); // 10秒超时 const modifiedRequest = new Request(actualUrl, { headers: request.headers, method: request.method, body: request.method !== 'GET' && request.method !== 'HEAD' ? request.body : undefined, redirect: 'follow', signal: controller.signal }); handleSpecialCases(modifiedRequest); // 添加一些必要的请求头 modifiedRequest.headers.set('User-Agent', 'Mozilla/5.0 (compatible; EdgeFunction/1.0)'); const response = await fetch(modifiedRequest); clearTimeout(timeoutId); const modifiedResponse = new Response(response.body, { status: response.status, statusText: response.statusText, headers: response.headers }); modifiedResponse.headers.set('Access-Control-Allow-Origin', '*'); modifiedResponse.headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); modifiedResponse.headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization'); return modifiedResponse; } catch (error) { let errorMessage = error.message; let errorType = 'Unknown Error'; if (error.name === 'AbortError') { errorType = 'Timeout Error'; errorMessage = 'Request timeout after 10 seconds'; } else if (error.message.includes('net_exception_connect_timeout')) { errorType = 'Connection Timeout'; errorMessage = 'Unable to connect to the target server'; } else if (error.message.includes('net_exception')) { errorType = 'Network Error'; errorMessage = 'Network connection failed'; } return new Response(JSON.stringify({ error: errorType, message: errorMessage, target_url: actualUrlStr, suggestions: [ 'Try again later', 'Check if the target URL is accessible', 'Ensure the target server allows cross-origin requests' ] }), { status: 502, headers: { 'content-type': 'application/json', 'Access-Control-Allow-Origin': '*' } }); } }
addEventListener('fetch', e => { e.respondWith(handleRequest(e.request)); });
|