├── .gitignore ├── README.md └── worker-openai-proxy.js /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .vscode 3 | 4 | # macOS 5 | .DS_Store 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ☁️ Cloudflare Workers OpenAI 代理 2 | 3 | ## 🚀 使用 4 | - [https://api.speechgpt.app](https://api.speechgpt.app) 5 | 6 | **注意**: 7 | - 该代理只供 [speechgpt.app](https://speechgpt.app) 使用。 8 | - 不保证稳定性,不保证长期可用,长期使用建议自行部署。 9 | 10 | ## 🛠️ 部署 11 | [![Deploy to Cloudflare Workers](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/hahahumble/worker-openai-proxy) 12 | 13 | ## 🔍 原理 14 | 该方案的原理是通过 Cloudflare Workers 代理 OpenAI API,配合自己可以正常访问的域名,实现在内地正常访问 OpenAI API。 15 | 16 | ## 🎁 捐赠 17 | 如果你觉得这个项目对你有帮助,可以考虑[捐赠](https://www.buymeacoffee.com/hahahumble),谢谢! 18 | 19 | ## 📚 参考 20 | 本项目基于以下项目修改而来: 21 | - https://github.com/noobnooc/noobnooc/discussions/9 22 | - https://developers.cloudflare.com/workers/platform/deploy-button/ 23 | 24 | ## 📝 说明 25 | 如何限制只有自己的域名可以访问? 26 | 27 | ```javascript 28 | const OPENAI_URL = 'https://api.openai.com'; 29 | 30 | addEventListener('fetch', event => { 31 | event.respondWith(handleRequest(event.request)); 32 | }); 33 | 34 | async function handleRequest(request) { 35 | const origin = request.headers.get('Origin'); 36 | const allowedOrigin = '<允许访问的域名>'; 37 | 38 | if (origin === allowedOrigin) { 39 | const url = new URL(request.url); 40 | url.host = OPENAI_URL.replace(/^https?:\/\//, ''); 41 | 42 | const modifiedRequest = new Request(url.toString(), { 43 | headers: request.headers, 44 | method: request.method, 45 | body: request.body, 46 | redirect: 'follow' 47 | }); 48 | 49 | const response = await fetch(modifiedRequest); 50 | const modifiedResponse = new Response(response.body, { 51 | status: response.status, 52 | statusText: response.statusText, 53 | headers: response.headers 54 | }); 55 | 56 | modifiedResponse.headers.set('Access-Control-Allow-Origin', allowedOrigin); 57 | 58 | return modifiedResponse; 59 | } else { 60 | return new Response('Unauthorized', { status: 403 }); 61 | } 62 | } 63 | ``` 64 | 将 `<允许访问的域名>` 替换为你自己的域名即可。 65 | -------------------------------------------------------------------------------- /worker-openai-proxy.js: -------------------------------------------------------------------------------- 1 | const OPENAI_URL = 'https://api.openai.com'; 2 | 3 | addEventListener('fetch', event => { 4 | event.respondWith(handleRequest(event.request)); 5 | }); 6 | 7 | async function handleRequest(request) { 8 | const url = new URL(request.url); 9 | url.host = OPENAI_URL.replace(/^https?:\/\//, ''); 10 | 11 | const modifiedRequest = new Request(url.toString(), { 12 | headers: request.headers, 13 | method: request.method, 14 | body: request.body, 15 | redirect: 'follow' 16 | }); 17 | 18 | const response = await fetch(modifiedRequest); 19 | const modifiedResponse = new Response(response.body, { 20 | status: response.status, 21 | statusText: response.statusText, 22 | headers: response.headers 23 | }); 24 | 25 | modifiedResponse.headers.set('Access-Control-Allow-Origin', '*'); 26 | 27 | return modifiedResponse; 28 | } 29 | --------------------------------------------------------------------------------