From 0ff71170e1aca2580324ad49cdbfa99f0af6d9ab Mon Sep 17 00:00:00 2001 From: wood chen Date: Mon, 6 Jan 2025 17:56:19 +0800 Subject: [PATCH] feat: enhance API request handling for WebSocket and HTTP protocols - Added support for WebSocket upgrade requests, converting HTTP/HTTPS to WS/WSS. - Improved handling of regular HTTP requests by creating a new target URL based on the API base URL. - Cleaned up request headers to remove potentially problematic headers. - Enhanced response handling by copying all response headers and setting CORS headers for better cross-origin support. - Improved error handling to include CORS headers in error responses. --- functions/api/index.js | 53 +++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/functions/api/index.js b/functions/api/index.js index 95c4af0..38b5a3e 100644 --- a/functions/api/index.js +++ b/functions/api/index.js @@ -10,16 +10,35 @@ export async function onRequest(context) { return new Response('API_BASEURL environment variable is not set', { status: 500 }); } - // 构建目标URL - const targetURL = new URL(path, env.API_BASEURL); + // 处理 WebSocket 升级请求 + if (request.headers.get('Upgrade') === 'websocket') { + const apiBaseUrl = new URL(env.API_BASEURL); + // 将 http/https 转换为 ws/wss + const wsBaseUrl = `${apiBaseUrl.protocol === 'https:' ? 'wss:' : 'ws:'}//${apiBaseUrl.host}`; + const targetURL = `${wsBaseUrl}${path}${url.search}`; + + return fetch(new Request(targetURL, { + method: request.method, + headers: request.headers, + body: request.body + })); + } - // 保留原始查询参数 + // 处理普通 HTTP 请求 + const apiBaseUrl = new URL(env.API_BASEURL); + const targetURL = new URL(path, apiBaseUrl.origin); targetURL.search = url.search; + // 创建新的请求头,移除可能导致问题的头部 + const newHeaders = new Headers(request.headers); + newHeaders.delete('host'); + newHeaders.delete('cf-connecting-ip'); + newHeaders.delete('cf-ipcountry'); + // 创建新的请求 - const newRequest = new Request(targetURL, { + const newRequest = new Request(targetURL.toString(), { method: request.method, - headers: request.headers, + headers: newHeaders, body: request.body, }); @@ -27,13 +46,29 @@ export async function onRequest(context) { // 转发请求到目标服务器 const response = await fetch(newRequest); - // 创建新的响应对象,保留原始响应的状态和头部 - return new Response(response.body, { + // 创建新的响应头,设置 CORS 和其他必要的头部 + const newResponse = new Response(response.body, { status: response.status, statusText: response.statusText, - headers: response.headers, }); + + // 复制所有响应头 + for (const [key, value] of response.headers.entries()) { + newResponse.headers.set(key, value); + } + + // 设置 CORS 头 + newResponse.headers.set('Access-Control-Allow-Origin', '*'); + newResponse.headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); + newResponse.headers.set('Access-Control-Allow-Headers', '*'); + + return newResponse; } catch (error) { - return new Response(`Proxy error: ${error.message}`, { status: 500 }); + return new Response(`Proxy error: ${error.message}`, { + status: 500, + headers: { + 'Access-Control-Allow-Origin': '*' + } + }); } }