3679 字
18 分钟
使用代理访问各AI平台的API
2025-04-28

项目地址#

AI Proxy

背景#

由于各个 AI 公司对于中国大陆限制了访问,导致我们无法直接访问这些地区的 API,所以需要使用代理来访问这些地区的 API。

比如 OpenAI 的 API 访问限制:

  • 中国大陆地区无法访问
  • 香港地区无法访问

解决方案#

在一台美国服务器上部署一个代理,然后使用这个代理来访问 AI API。

部署#

我这里添加了 mongoose 来存储请求记录,所以需要安装 mongoose,如果你不需要则跳过。

# 初始化项目
npm init -y
# 安装 mongoose
npm install mongoose

使用 pm2 来启动项目:

# 启动项目
pm2 start ai-proxy.js --name ai-proxy
# 使用环境变量
MONGODB_URI=mongodb://localhost:27017/ai-proxy PORT=8088 HOST=0.0.0.0 pm2 start ai-proxy.js --name ai-proxy
# 查看项目
pm2 list
# 停止项目
pm2 stop ai-proxy

代码#

代理代码#

// ai-proxy.js
// 导入 Node.js 内置模块
const http = require('http');
const https = require('https'); // 需要根据目标URL的协议选择 http 或 https
const fs = require('fs');
const path = require('path');
const { URL } = require('url');
const mongoose = require('mongoose');

// 获取环境变量
const PORT = process.env.PORT || 8088;
const HOST = process.env.HOST || '0.0.0.0';
const MONGODB_URI = process.env.MONGODB_URI || '';

// 如果 MONGODB_URI 存在,则使用 MongoDB 存储请求记录
let AiProxyUsage = null;
if (MONGODB_URI) {
  try {
    mongoose.connect(MONGODB_URI, { useNewUrlParser: true, useUnifiedTopology: true });
    const AiProxyUsageSchema = new mongoose.Schema({
      type: {
        type: String,
        required: true,
      },
      createTime: {
        type: String,
        required: true,
      },
    });
    AiProxyUsage = mongoose?.models?.AiProxyUsage || mongoose.model('AiProxyUsage', AiProxyUsageSchema);
  } catch (error) {
    console.error(`Error connecting to MongoDB: ${error}`);
  }
}

// API 路由映射
const apiMapping = {
  '/discord': 'https://discord.com/api',
  '/telegram': 'https://api.telegram.org',
  '/openai': 'https://api.openai.com',
  '/claude': 'https://api.anthropic.com',
  '/gemini': 'https://generativelanguage.googleapis.com',
  '/meta': 'https://www.meta.ai/api', // 注意:实际的Meta API可能不同
  '/groq': 'https://api.groq.com/openai',
  '/xai': 'https://api.x.ai',
  '/cohere': 'https://api.cohere.ai',
  '/huggingface': 'https://api-inference.huggingface.co',
  '/together': 'https://api.together.xyz',
  '/novita': 'https://api.novita.ai',
  '/portkey': 'https://api.portkey.ai',
  '/fireworks': 'https://api.fireworks.ai',
  '/openrouter': 'https://openrouter.ai/api'
};

// 允许转发到目标 API 的请求头列表(小写)
const allowedHeaders = ['accept', 'content-type', 'authorization'];

// 辅助函数:从路径名中提取匹配的前缀和剩余部分
function extractPrefixAndRest(pathname, prefixes) {
  for (const prefix of prefixes) {
    if (pathname.startsWith(prefix)) {
      return [prefix, pathname.slice(prefix.length)];
    }
  }
  return [null, null];
}

// 创建 HTTP 服务器
const server = http.createServer(async (req, res) => {
  // 解析请求 URL
  // Node.js 的 req.url 只包含路径和查询参数,需要结合 host 来构造完整 URL
  const requestUrl = new URL(req.url, `http://${req.headers.host}`);
  const pathname = requestUrl.pathname;

  // 1. 处理根路径和 index.html -> 提供本地 HTML 文件
  if (pathname === '/' || pathname === '/index.html') {
    const filePath = path.join(__dirname, 'index.html'); // 假设 index.html 在脚本同级目录下
    fs.readFile(filePath, (err, data) => {
      if (err) {
        console.error(`Error reading index.html: ${err}`);
        res.writeHead(500, { 'Content-Type': 'text/plain' });
        res.end('Internal Server Error - Could not read index.html');
      } else {
        res.writeHead(200, { 'Content-Type': 'text/html' });
        res.end(data);
      }
    });
    return; // 结束请求处理
  }

  // 2. 处理 robots.txt
  if (pathname === '/robots.txt') {
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.end('User-agent: *\nDisallow: /');
    return; // 结束请求处理
  }

  // 3. 处理 API 代理
  const [prefix, rest] = extractPrefixAndRest(pathname, Object.keys(apiMapping));

  if (!prefix) {
    // 如果路径不匹配任何已知前缀,返回 404
    res.writeHead(404, { 'Content-Type': 'text/plain' });
    res.end('Not Found');
    return; // 结束请求处理
  }

  // 构建目标 API 的 URL
  const targetBaseUrl = apiMapping[prefix];
  const targetUrl = `${targetBaseUrl}${rest}${requestUrl.search}`; // 包含查询参数

  // 准备转发请求的选项
  const options = {
    method: req.method,
    headers: {},
    // agent: targetBaseUrl.startsWith('https') ? new https.Agent({ keepAlive: true }) : new http.Agent({ keepAlive: true }) // 可选:使用 agent 进行连接复用
  };

  // 复制允许的请求头
  for (const key in req.headers) {
    if (allowedHeaders.includes(key.toLowerCase())) {
      options.headers[key] = req.headers[key];
    }
  }
  // 确保 host 头部设置为目标主机,而不是代理服务器的主机
  options.headers['host'] = new URL(targetBaseUrl).host;


  // 选择 http 或 https 模块进行请求
  const protocol = targetBaseUrl.startsWith('https') ? https : http;

  // 创建代理请求
  const proxyReq = protocol.request(targetUrl, options, (proxyRes) => {
    // 设置响应头
    // 复制目标服务器的响应头到客户端响应
    const responseHeaders = { ...proxyRes.headers }; // 复制一份

    // 添加额外的安全响应头
    responseHeaders['X-Content-Type-Options'] = 'nosniff';
    responseHeaders['X-Frame-Options'] = 'DENY';
    responseHeaders['Referrer-Policy'] = 'no-referrer';
    // 可以选择性地删除或修改某些从目标服务器传来的头,例如 'transfer-encoding'
    // delete responseHeaders['transfer-encoding'];

    // 将目标服务器的状态码和处理后的响应头写入客户端响应
    res.writeHead(proxyRes.statusCode, responseHeaders);

    // 将目标服务器的响应体流式传输到客户端响应
    proxyRes.pipe(res, { end: true });
  });

  // 处理代理请求错误
  proxyReq.on('error', (err) => {
    console.error(`Proxy request error: ${err}`);
    if (!res.headersSent) {
      res.writeHead(502, { 'Content-Type': 'text/plain' }); // 502 Bad Gateway
    }
    res.end('Bad Gateway');
  });

  // 使用 MongoDB 存储请求记录
  if (MONGODB_URI && AiProxyUsage) {
    const usage = new AiProxyUsage({
      type: prefix,
      createTime: new Date().toISOString(),
    });
    usage.save();
  }

  // 将客户端请求体流式传输到代理请求
  // 对于 GET, HEAD 等没有 body 的请求,这不会做任何事
  req.pipe(proxyReq, { end: true });

});

// 启动服务器
server.listen(PORT, HOST, () => {
  console.log(`Node.js proxy server running on http://${HOST}:${PORT}`);
  console.log(`Root path serves './index.html'`);
  console.log('Proxying the following prefixes:');
  Object.keys(apiMapping).forEach(prefix => {
    console.log(`  ${prefix} -> ${apiMapping[prefix]}`);
  });
});

// 可选:更优雅地处理关闭信号,以便 pm2 reload/stop
process.on('SIGINT', () => {
  console.log('SIGINT signal received: closing HTTP server');
  server.close(() => {
    console.log('HTTP server closed');
    process.exit(0);
  });
});

前端页面#

<!-- index.html -->
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="icon"
    href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🚀</text></svg>">
  <title>AI Proxy - 简单、安全、高效</title>
  <!-- seo -->
  <meta name="description" content="AI Proxy - 提供简单、安全、高效、免费的 API 代理服务,让您的 AI 应用更加稳定、快速。">
  <meta name="keywords" content="AI Proxy, API Proxy, AI, 代理, 简单, 安全, 高效">
  <meta name="robots" content="index, follow">
  <meta name="googlebot" content="index, follow">
  <meta name="bingbot" content="index, follow">
  <script src="https://cdn.tailwindcss.com?plugins=forms,typography,aspect-ratio,line-clamp"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/highlight.js@11.9.0/lib/languages/javascript.min.js"></script>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@11.9.0/styles/atom-one-light.min.css">
  <script>
    // Tailwind 配置
    tailwind.config = {
      theme: {
        extend: {
          fontFamily: {
            sans: ['-apple-system', 'BlinkMacSystemFont', 'SF Pro Display', 'SF Pro Text', 'Helvetica Neue', 'Arial', 'sans-serif'],
            mono: ['SF Mono', 'SFMono-Regular', 'Menlo', 'Monaco', 'Consolas', '"Liberation Mono"', '"Courier New"', 'monospace'],
          },
          maxWidth: {
            'screen-xl': '1280px',
          },
          colors: {
            'apple-blue': {
              50: '#E8F2FF',
              100: '#C9E0FF',
              200: '#A6CDFF',
              300: '#83BAFF',
              400: '#5FA7FF',
              500: '#3C94FF',
              600: '#0071E3', // Apple 按钮蓝
              700: '#0051A5',
              800: '#00356B',
              900: '#001A36',
            },
            'apple-gray': {
              50: '#F9F9F9', // 浅灰背景
              100: '#F5F5F7', // Apple 官网背景灰
              200: '#E8E8ED',
              300: '#D2D2D7',
              400: '#B1B1B6',
              500: '#86868B', // Apple 官网文字灰
              600: '#6E6E73',
              700: '#414144',
              800: '#2D2D2F',
              900: '#1D1D1F', // Apple 官网深色文字
            }
          },
          boxShadow: {
            'apple': '0 2px 5px -1px rgba(0, 0, 0, 0.1), 0 2px 5px -1px rgba(0, 0, 0, 0.06)',
            'apple-md': '0 4px 12px -2px rgba(0, 0, 0, 0.08), 0 2px 6px -1px rgba(0, 0, 0, 0.05)',
            'apple-lg': '0 10px 20px -5px rgba(0, 0, 0, 0.1), 0 5px 10px -5px rgba(0, 0, 0, 0.04)',
          },
          borderRadius: {
            'apple': '10px',
            'apple-sm': '6px'
          }
        }
      }
    }
  </script>
  <style type="text/tailwindcss">
    body {
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      letter-spacing: -0.2px;
    }
    .copy-btn:disabled svg {
      color: theme('colors.green.500');
    }
    /* 苹果风格滚动条 */
    ::-webkit-scrollbar {
      width: 8px;
      height: 8px;
    }
    ::-webkit-scrollbar-track {
      background: theme('colors.apple-gray.100');
      border-radius: 100px;
    }
    ::-webkit-scrollbar-thumb {
      background: theme('colors.apple-gray.300');
      border-radius: 100px;
    }
    ::-webkit-scrollbar-thumb:hover {
      background: theme('colors.apple-gray.400');
    }
    
    /* 代码高亮自定义样式 */
    pre {
      position: relative;
      background: theme('colors.apple-gray.50');
      border-radius: theme('borderRadius.apple-sm');
      margin: 0;
      padding: 1rem;
      overflow: auto;
    }
    pre code {
      font-family: theme('fontFamily.mono');
      font-size: 0.9rem;
      line-height: 1.5;
      display: block;
      padding: 0;
    }
    /* 关键词高亮样式 */
    .hljs-keyword {
      color: #0033cc;
      font-weight: 500;
    }
    /* 字符串高亮样式 */
    .hljs-string {
      color: #067d17;
    }
    /* 注释高亮样式 */
    .hljs-comment {
      color: #888888;
      font-style: italic;
    }
    /* 函数高亮样式 */
    .hljs-function {
      color: #6f42c1;
    }
    /* 数字高亮样式 */
    .hljs-number {
      color: #986801;
    }
    /* 属性高亮样式 */
    .hljs-attr, .hljs-property {
      color: #e36209;
    }
    .code-container {
      position: relative;
      border-radius: theme('borderRadius.apple-sm');
      box-shadow: theme('boxShadow.apple');
      overflow: hidden;
      width: 100%;
      max-width: 100%;
      margin: 0 auto;
    }
    .code-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 0.5rem 1rem;
      background: theme('colors.apple-gray.100');
      border-bottom: 1px solid theme('colors.apple-gray.200');
    }
    .code-title {
      font-size: 0.85rem;
      font-weight: 500;
      color: theme('colors.apple-gray.600');
    }
    .code-copy-btn {
      background: transparent;
      border: none;
      cursor: pointer;
      padding: 0.25rem;
      border-radius: 4px;
      color: theme('colors.apple-gray.500');
      transition: all 0.2s;
    }
    .code-copy-btn:hover {
      color: theme('colors.apple-blue.600');
      background: rgba(0, 0, 0, 0.05);
    }
  </style>
  <script>
    // 确保highlight.js在页面加载完成后立即执行高亮
    window.onload = function () {
      hljs.configure({
        languages: ['javascript']
      });
      hljs.highlightAll();
    };
  </script>
</head>

<body class="bg-apple-gray-50 text-apple-gray-900 font-sans flex flex-col items-center min-h-screen py-8 px-4">

  <div class="w-full max-w-screen-xl space-y-6 md:space-y-8">

    <div class="bg-gradient-to-br from-blue-600 to-blue-400 rounded-apple shadow-apple-lg text-center p-8 md:p-12">
      <h1 class="text-4xl md:text-6xl font-medium tracking-tight mb-2 md:mb-3 text-white">AI Proxy</h1>
      <h2 class="text-xl md:text-2xl font-light mb-6 md:mb-8 text-white/90">简单、安全、高效</h2>
      <p class="text-base md:text-xl leading-relaxed font-light text-white/90 mx-auto">
        使用美国西部服务器,免费提供简单、安全、高效的 API 代理服务,让您的 AI 应用更加稳定、快速。
      </p>
    </div>

    <div class="bg-white rounded-apple shadow-apple-md p-6 md:p-8">
      <h2 class="text-xl md:text-2xl font-medium text-apple-gray-900 mb-3 text-left">可用端点</h2>
      <p class="text-sm md:text-base font-light text-apple-gray-600 mb-6">选择并配置您需要的 AI 服务接口</p>
      <div class="overflow-x-auto rounded-apple-sm">
        <table class="w-full text-left text-sm md:text-base table-fixed">
          <thead>
            <tr>
              <th class="w-[18%] pb-3 pt-2 px-3 md:px-4 font-medium text-apple-gray-600 border-b border-apple-gray-200">
                服务
              </th>
              <th class="w-[42%] pb-3 pt-2 px-3 md:px-4 font-medium text-apple-gray-600 border-b border-apple-gray-200">
                代理地址
              </th>
              <th class="w-[40%] pb-3 pt-2 px-3 md:px-4 font-medium text-apple-gray-600 border-b border-apple-gray-200">
                原始地址</th>
            </tr>
          </thead>
          <tbody class="divide-y divide-apple-gray-200">
            <tr>
              <td class="py-3.5 px-3 md:px-4 font-medium text-apple-gray-800 align-middle">OpenAI</td>
              <td class="py-3.5 px-3 md:px-4 align-middle">
                <div class="flex items-center gap-1">
                  <span
                    class="font-mono text-apple-gray-600 break-words min-w-0 text-sm">https://ai-proxy.mihouo.com/openai</span>
                  <button
                    class="copy-btn flex-shrink-0 p-1.5 rounded-full text-apple-gray-500 hover:bg-apple-gray-100 hover:text-apple-blue-600 focus:outline-none focus:ring-1 focus:ring-apple-blue-500 transition-colors duration-150"
                    data-copy-text="https://ai-proxy.mihouo.com/openai" aria-label="复制地址">
                  </button>
                </div>
              </td>
              <td class="py-3.5 px-3 md:px-4 align-middle">
                <a href="https://platform.openai.com/docs/api-reference" target="_blank" rel="noopener noreferrer"
                  class="font-mono text-apple-blue-600 hover:underline break-words text-sm">https://api.openai.com</a>
              </td>
            </tr>
            <tr>
              <td class="py-3.5 px-3 md:px-4 font-medium text-apple-gray-800 align-middle">Anthropic Claude</td>
              <td class="py-3.5 px-3 md:px-4 align-middle">
                <div class="flex items-center gap-1">
                  <span
                    class="font-mono text-apple-gray-600 break-words min-w-0 text-sm">https://ai-proxy.mihouo.com/claude</span>
                  <button
                    class="copy-btn flex-shrink-0 p-1.5 rounded-full text-apple-gray-500 hover:bg-apple-gray-100 hover:text-apple-blue-600 focus:outline-none focus:ring-1 focus:ring-apple-blue-500 transition-colors duration-150"
                    data-copy-text="https://ai-proxy.mihouo.com/claude" aria-label="复制地址">
                  </button>
                </div>
              </td>
              <td class="py-3.5 px-3 md:px-4 align-middle">
                <a href="https://docs.anthropic.com/claude/reference/getting-started-with-the-api" target="_blank"
                  rel="noopener noreferrer"
                  class="font-mono text-apple-blue-600 hover:underline break-words text-sm">https://api.anthropic.com</a>
              </td>
            </tr>
            <tr>
              <td class="py-3.5 px-3 md:px-4 font-medium text-apple-gray-800 align-middle">Google Gemini</td>
              <td class="py-3.5 px-3 md:px-4 align-middle">
                <div class="flex items-center gap-1">
                  <span
                    class="font-mono text-apple-gray-600 break-words min-w-0 text-sm">https://ai-proxy.mihouo.com/gemini</span>
                  <button
                    class="copy-btn flex-shrink-0 p-1.5 rounded-full text-apple-gray-500 hover:bg-apple-gray-100 hover:text-apple-blue-600 focus:outline-none focus:ring-1 focus:ring-apple-blue-500 transition-colors duration-150"
                    data-copy-text="https://ai-proxy.mihouo.com/gemini" aria-label="复制地址">
                  </button>
                </div>
              </td>
              <td class="py-3.5 px-3 md:px-4 align-middle">
                <a href="https://ai.google.dev/api/rest" target="_blank" rel="noopener noreferrer"
                  class="font-mono text-apple-blue-600 hover:underline break-words text-sm">https://generativelanguage.googleapis.com</a>
              </td>
            </tr>
            <tr>
              <td class="py-3.5 px-3 md:px-4 font-medium text-apple-gray-800 align-middle">Groq</td>
              <td class="py-3.5 px-3 md:px-4 align-middle">
                <div class="flex items-center gap-1">
                  <span
                    class="font-mono text-apple-gray-600 break-words min-w-0 text-sm">https://ai-proxy.mihouo.com/groq</span>
                  <button
                    class="copy-btn flex-shrink-0 p-1.5 rounded-full text-apple-gray-500 hover:bg-apple-gray-100 hover:text-apple-blue-600 focus:outline-none focus:ring-1 focus:ring-apple-blue-500 transition-colors duration-150"
                    data-copy-text="https://ai-proxy.mihouo.com/groq" aria-label="复制地址">
                  </button>
                </div>
              </td>
              <td class="py-3.5 px-3 md:px-4 align-middle">
                <a href="https://console.groq.com/docs/api-reference" target="_blank" rel="noopener noreferrer"
                  class="font-mono text-apple-blue-600 hover:underline break-words text-sm">https://api.groq.com</a>
              </td>
            </tr>
            <tr>
              <td class="py-3.5 px-3 md:px-4 font-medium text-apple-gray-800 align-middle">Meta AI</td>
              <td class="py-3.5 px-3 md:px-4 align-middle">
                <div class="flex items-center gap-1">
                  <span
                    class="font-mono text-apple-gray-600 break-words min-w-0 text-sm">https://ai-proxy.mihouo.com/meta</span>
                  <button
                    class="copy-btn flex-shrink-0 p-1.5 rounded-full text-apple-gray-500 hover:bg-apple-gray-100 hover:text-apple-blue-600 focus:outline-none focus:ring-1 focus:ring-apple-blue-500 transition-colors duration-150"
                    data-copy-text="https://ai-proxy.mihouo.com/meta" aria-label="复制地址">
                  </button>
                </div>
              </td>
              <td class="py-3.5 px-3 md:px-4 align-middle">
                <a href="https://developers.facebook.com/docs/graph-api" target="_blank" rel="noopener noreferrer"
                  class="font-mono text-apple-blue-600 hover:underline break-words text-sm">https://developers.facebook.com/docs/graph-api</a>
              </td>
            </tr>
            <tr>
              <td class="py-3.5 px-3 md:px-4 font-medium text-apple-gray-800 align-middle">Cohere</td>
              <td class="py-3.5 px-3 md:px-4 align-middle">
                <div class="flex items-center gap-1">
                  <span
                    class="font-mono text-apple-gray-600 break-words min-w-0 text-sm">https://ai-proxy.mihouo.com/cohere</span>
                  <button
                    class="copy-btn flex-shrink-0 p-1.5 rounded-full text-apple-gray-500 hover:bg-apple-gray-100 hover:text-apple-blue-600 focus:outline-none focus:ring-1 focus:ring-apple-blue-500 transition-colors duration-150"
                    data-copy-text="https://ai-proxy.mihouo.com/cohere" aria-label="复制地址">
                  </button>
                </div>
              </td>
              <td class="py-3.5 px-3 md:px-4 align-middle">
                <a href="https://docs.cohere.com/reference/about" target="_blank" rel="noopener noreferrer"
                  class="font-mono text-apple-blue-600 hover:underline break-words text-sm">https://api.cohere.ai</a>
              </td>
            </tr>
            <tr>
              <td class="py-3.5 px-3 md:px-4 font-medium text-apple-gray-800 align-middle">Together AI</td>
              <td class="py-3.5 px-3 md:px-4 align-middle">
                <div class="flex items-center gap-1">
                  <span
                    class="font-mono text-apple-gray-600 break-words min-w-0 text-sm">https://ai-proxy.mihouo.com/together</span>
                  <button
                    class="copy-btn flex-shrink-0 p-1.5 rounded-full text-apple-gray-500 hover:bg-apple-gray-100 hover:text-apple-blue-600 focus:outline-none focus:ring-1 focus:ring-apple-blue-500 transition-colors duration-150"
                    data-copy-text="https://ai-proxy.mihouo.com/together" aria-label="复制地址">
                  </button>
                </div>
              </td>
              <td class="py-3.5 px-3 md:px-4 align-middle">
                <a href="https://docs.together.ai/reference/inference" target="_blank" rel="noopener noreferrer"
                  class="font-mono text-apple-blue-600 hover:underline break-words text-sm">https://api.together.xyz</a>
              </td>
            </tr>
            <tr>
              <td class="py-3.5 px-3 md:px-4 font-medium text-apple-gray-800 align-middle">X.ai (Grok)</td>
              <td class="py-3.5 px-3 md:px-4 align-middle">
                <div class="flex items-center gap-1">
                  <span
                    class="font-mono text-apple-gray-600 break-words min-w-0 text-sm">https://ai-proxy.mihouo.com/xai</span>
                  <button
                    class="copy-btn flex-shrink-0 p-1.5 rounded-full text-apple-gray-500 hover:bg-apple-gray-100 hover:text-apple-blue-600 focus:outline-none focus:ring-1 focus:ring-apple-blue-500 transition-colors duration-150"
                    data-copy-text="https://ai-proxy.mihouo.com/xai" aria-label="复制地址">
                  </button>
                </div>
              </td>
              <td class="py-3.5 px-3 md:px-4 align-middle">
                <a href="https://docs.x.ai/" target="_blank" rel="noopener noreferrer"
                  class="font-mono text-apple-blue-600 hover:underline break-words text-sm">https://api.x.ai</a>
              </td>
            </tr>
            <tr>
              <td class="py-3.5 px-3 md:px-4 font-medium text-apple-gray-800 align-middle">Hugging Face</td>
              <td class="py-3.5 px-3 md:px-4 align-middle">
                <div class="flex items-center gap-1">
                  <span
                    class="font-mono text-apple-gray-600 break-words min-w-0 text-sm">https://ai-proxy.mihouo.com/huggingface</span>
                  <button
                    class="copy-btn flex-shrink-0 p-1.5 rounded-full text-apple-gray-500 hover:bg-apple-gray-100 hover:text-apple-blue-600 focus:outline-none focus:ring-1 focus:ring-apple-blue-500 transition-colors duration-150"
                    data-copy-text="https://ai-proxy.mihouo.com/huggingface" aria-label="复制地址">
                  </button>
                </div>
              </td>
              <td class="py-3.5 px-3 md:px-4 align-middle">
                <a href="https://huggingface.co/docs/api-inference/index" target="_blank" rel="noopener noreferrer"
                  class="font-mono text-apple-blue-600 hover:underline break-words text-sm">https://api-inference.huggingface.co</a>
              </td>
            </tr>
            <tr>
              <td class="py-3.5 px-3 md:px-4 font-medium text-apple-gray-800 align-middle">OpenRouter</td>
              <td class="py-3.5 px-3 md:px-4 align-middle">
                <div class="flex items-center gap-1">
                  <span
                    class="font-mono text-apple-gray-600 break-words min-w-0 text-sm">https://ai-proxy.mihouo.com/openrouter</span>
                  <button
                    class="copy-btn flex-shrink-0 p-1.5 rounded-full text-apple-gray-500 hover:bg-apple-gray-100 hover:text-apple-blue-600 focus:outline-none focus:ring-1 focus:ring-apple-blue-500 transition-colors duration-150"
                    data-copy-text="https://ai-proxy.mihouo.com/openrouter" aria-label="复制地址">
                  </button>
                </div>
              </td>
              <td class="py-3.5 px-3 md:px-4 align-middle">
                <a href="https://openrouter.ai/docs" target="_blank" rel="noopener noreferrer"
                  class="font-mono text-apple-blue-600 hover:underline break-words text-sm">https://openrouter.ai/api</a>
              </td>
            </tr>
            <tr>
              <td class="py-3.5 px-3 md:px-4 font-medium text-apple-gray-800 align-middle">Fireworks AI</td>
              <td class="py-3.5 px-3 md:px-4 align-middle">
                <div class="flex items-center gap-1">
                  <span
                    class="font-mono text-apple-gray-600 break-words min-w-0 text-sm">https://ai-proxy.mihouo.com/fireworks</span>
                  <button
                    class="copy-btn flex-shrink-0 p-1.5 rounded-full text-apple-gray-500 hover:bg-apple-gray-100 hover:text-apple-blue-600 focus:outline-none focus:ring-1 focus:ring-apple-blue-500 transition-colors duration-150"
                    data-copy-text="https://ai-proxy.mihouo.com/fireworks" aria-label="复制地址">
                  </button>
                </div>
              </td>
              <td class="py-3.5 px-3 md:px-4 align-middle">
                <a href="https://readme.fireworks.ai/reference/introduction" target="_blank" rel="noopener noreferrer"
                  class="font-mono text-apple-blue-600 hover:underline break-words text-sm">https://api.fireworks.ai</a>
              </td>
            </tr>
            <tr>
              <td class="py-3.5 px-3 md:px-4 font-medium text-apple-gray-800 align-middle">Portkey AI</td>
              <td class="py-3.5 px-3 md:px-4 align-middle">
                <div class="flex items-center gap-1">
                  <span
                    class="font-mono text-apple-gray-600 break-words min-w-0 text-sm">https://ai-proxy.mihouo.com/portkey</span>
                  <button
                    class="copy-btn flex-shrink-0 p-1.5 rounded-full text-apple-gray-500 hover:bg-apple-gray-100 hover:text-apple-blue-600 focus:outline-none focus:ring-1 focus:ring-apple-blue-500 transition-colors duration-150"
                    data-copy-text="https://ai-proxy.mihouo.com/portkey" aria-label="复制地址">
                  </button>
                </div>
              </td>
              <td class="py-3.5 px-3 md:px-4 align-middle">
                <a href="https://portkey.ai/docs/api-reference/introduction" target="_blank" rel="noopener noreferrer"
                  class="font-mono text-apple-blue-600 hover:underline break-words text-sm">https://api.portkey.ai</a>
              </td>
            </tr>
            <tr>
              <td class="py-3.5 px-3 md:px-4 font-medium text-apple-gray-800 align-middle">Novita AI</td>
              <td class="py-3.5 px-3 md:px-4 align-middle">
                <div class="flex items-center gap-1">
                  <span
                    class="font-mono text-apple-gray-600 break-words min-w-0 text-sm">https://ai-proxy.mihouo.com/novita</span>
                  <button
                    class="copy-btn flex-shrink-0 p-1.5 rounded-full text-apple-gray-500 hover:bg-apple-gray-100 hover:text-apple-blue-600 focus:outline-none focus:ring-1 focus:ring-apple-blue-500 transition-colors duration-150"
                    data-copy-text="https://ai-proxy.mihouo.com/novita" aria-label="复制地址">
                  </button>
                </div>
              </td>
              <td class="py-3.5 px-3 md:px-4 align-middle">
                <a href="https://docs.novita.ai/api-reference" target="_blank" rel="noopener noreferrer"
                  class="font-mono text-apple-blue-600 hover:underline break-words text-sm">https://api.novita.ai</a>
              </td>
            </tr>
            <tr>
              <td class="py-3.5 px-3 md:px-4 font-medium text-apple-gray-800 align-middle">Discord</td>
              <td class="py-3.5 px-3 md:px-4 align-middle">
                <div class="flex items-center gap-1">
                  <span
                    class="font-mono text-apple-gray-600 break-words min-w-0 text-sm">https://ai-proxy.mihouo.com/discord</span>
                  <button
                    class="copy-btn flex-shrink-0 p-1.5 rounded-full text-apple-gray-500 hover:bg-apple-gray-100 hover:text-apple-blue-600 focus:outline-none focus:ring-1 focus:ring-apple-blue-500 transition-colors duration-150"
                    data-copy-text="https://ai-proxy.mihouo.com/discord" aria-label="复制地址">
                  </button>
                </div>
              </td>
              <td class="py-3.5 px-3 md:px-4 align-middle">
                <a href="https://discord.com/developers/docs/intro" target="_blank" rel="noopener noreferrer"
                  class="font-mono text-apple-blue-600 hover:underline break-words text-sm">https://discord.com/api</a>
              </td>
            </tr>
            <tr>
              <td class="py-3.5 px-3 md:px-4 font-medium text-apple-gray-800 align-middle">Telegram</td>
              <td class="py-3.5 px-3 md:px-4 align-middle">
                <div class="flex items-center gap-1">
                  <span
                    class="font-mono text-apple-gray-600 break-words min-w-0 text-sm">https://ai-proxy.mihouo.com/telegram</span>
                  <button
                    class="copy-btn flex-shrink-0 p-1.5 rounded-full text-apple-gray-500 hover:bg-apple-gray-100 hover:text-apple-blue-600 focus:outline-none focus:ring-1 focus:ring-apple-blue-500 transition-colors duration-150"
                    data-copy-text="https://ai-proxy.mihouo.com/telegram" aria-label="复制地址">
                  </button>
                </div>
              </td>
              <td class="py-3.5 px-3 md:px-4 align-middle">
                <a href="https://core.telegram.org/bots/api" target="_blank" rel="noopener noreferrer"
                  class="font-mono text-apple-blue-600 hover:underline break-words text-sm">https://core.telegram.org/bots/api</a>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>

    <!-- 使用示例 -->
    <div class="bg-white rounded-apple shadow-apple-md p-6 md:p-8 text-center">
      <h2 class="text-xl md:text-2xl font-medium mb-4 text-apple-gray-800">使用示例</h2>
      <p class="text-base md:text-lg font-light text-apple-gray-600 mb-6">通过几行简单的代码,即可轻松连接到 API 服务</p>

      <div class="code-container mx-auto text-left">
        <div class="code-header">
          <span class="code-title">JavaScript</span>
          <button class="code-copy-btn" aria-label="复制代码">
            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="w-4 h-4"
              viewBox="0 0 16 16">
              <path
                d="M4 1.5H3a2 2 0 0 0-2 2V14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3.5a2 2 0 0 0-2-2h-1v1h1a1 1 0 0 1 1 1V14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V3.5a1 1 0 0 1 1-1h1v-1z">
              </path>
              <path
                d="M9.5 1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-1a.5.5 0 0 1 .5-.5h3zm-3-1A1.5 1.5 0 0 0 5 1.5v1A1.5 1.5 0 0 0 6.5 4h3A1.5 1.5 0 0 0 11 2.5v-1A1.5 1.5 0 0 0 9.5 0h-3z">
              </path>
            </svg>
          </button>
        </div>
        <pre><code class="language-javascript">// 导入 OpenAI 库
const { OpenAI } = require('openai');

// 创建 API 客户端实例
const openai = new OpenAI({
  apiKey: 'sk-**************************************',
  baseURL: 'https://ai-proxy.mihouo.com/openai/v1',
});

// 发送请求示例
async function generateResponse() {
  const response = await openai.chat.completions.create({
    model: "gpt-3.5-turbo",
    messages: [
      { role: "system", content: "你是一个专业的AI助手。" },
      { role: "user", content: "你好,请介绍一下自己。" }
    ],
    temperature: 0.7,
  });
  
  console.log(response.choices[0].message.content);
}</code></pre>
      </div>
    </div>

    <div class="bg-white rounded-apple shadow-apple-md p-6 text-center">
      <div class="flex flex-col md:flex-row items-center justify-center space-y-2 md:space-y-0 md:space-x-8">
        <p class="flex items-center text-apple-gray-500 text-sm">
          <span class="inline-block w-2.5 h-2.5 bg-green-500 rounded-full mr-2"></span>
          <span class="font-light">状态:</span>
          <span class="text-apple-gray-700 font-medium ml-1">运行中</span>
        </p>
        <p class="text-sm text-apple-gray-500">
          <span class="font-light">北京时间:</span>
          <span id="live-time" class="font-medium text-apple-gray-700 ml-1">加载中...</span>
        </p>
      </div>
    </div>

  </div>
  <script>
    // 时间更新脚本
    function updateLiveTime() {
      const timeElement = document.getElementById('live-time');
      if (timeElement) {
        const now = new Date();
        const beijingTime = now.toLocaleString('zh-CN', {
          timeZone: 'Asia/Shanghai',
          hour12: false,
          year: 'numeric', month: '2-digit', day: '2-digit',
          hour: '2-digit', minute: '2-digit', second: '2-digit'
        });
        timeElement.textContent = beijingTime.replace(/[\/]/g, '-').replace(/\s+/g, ' ').trim();
      }
    }
    updateLiveTime();
    setInterval(updateLiveTime, 1000);

    // --- 复制按钮脚本 ---
    document.addEventListener('DOMContentLoaded', () => {
      const copyButtons = document.querySelectorAll('.copy-btn');

      // 确保在DOM加载完成后再次尝试高亮
      hljs.configure({
        languages: ['javascript']
      });
      hljs.highlightAll();

      // 代码块复制功能
      const codeBlock = document.querySelector('pre code');
      const codeCopyBtn = document.querySelector('.code-copy-btn');

      if (codeBlock && codeCopyBtn) {
        codeCopyBtn.addEventListener('click', () => {
          const code = codeBlock.textContent;

          navigator.clipboard.writeText(code).then(() => {
            // 复制成功反馈
            const originalSvg = codeCopyBtn.innerHTML;

            // 替换为成功图标
            codeCopyBtn.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="w-4 h-4 text-green-500" viewBox="0 0 16 16"><path d="M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z"/></svg>`;

            // 1.5秒后恢复原始图标
            setTimeout(() => {
              codeCopyBtn.innerHTML = originalSvg;
            }, 1500);
          }).catch(err => {
            console.error('无法复制代码: ', err);
            alert('复制失败,请手动复制。');
          });
        });
      }

      // SVG Icons - 苹果风格图标
      const originalIconSvg = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="w-4 h-4" viewBox="0 0 16 16"><path d="M4 1.5H3a2 2 0 0 0-2 2V14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3.5a2 2 0 0 0-2-2h-1v1h1a1 1 0 0 1 1 1V14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V3.5a1 1 0 0 1 1-1h1v-1z"/><path d="M9.5 1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-1a.5.5 0 0 1 .5-.5h3zm-3-1A1.5 1.5 0 0 0 5 1.5v1A1.5 1.5 0 0 0 6.5 4h3A1.5 1.5 0 0 0 11 2.5v-1A1.5 1.5 0 0 0 9.5 0h-3z"/></svg>`;
      const successIconSvg = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="w-4 h-4" viewBox="0 0 16 16"><path d="M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z"/></svg>`;

      copyButtons.forEach(button => {
        button.innerHTML = originalIconSvg; // 设置初始图标

        button.addEventListener('click', () => {
          const textToCopy = button.dataset.copyText;

          if (!textToCopy) {
            console.error('无复制内容');
            return;
          }
          if (!navigator.clipboard) {
            console.error('剪贴板 API 不可用');
            alert('抱歉,您的浏览器不支持或未启用剪贴板功能。');
            return;
          }

          navigator.clipboard.writeText(textToCopy).then(() => {
            // 成功反馈 - 苹果风格的平滑过渡
            button.innerHTML = successIconSvg;
            button.disabled = true;

            setTimeout(() => {
              button.innerHTML = originalIconSvg; // 恢复图标
              button.disabled = false;
            }, 1500); // 1.5秒后恢复

          }).catch(err => {
            console.error('无法复制文本: ', err);
            alert('复制失败,请手动复制。');
          });
        });
      });
    });
  </script>
</body>

</html>
使用代理访问各AI平台的API
https://www.mihouo.com/posts/tool-share/ai-api-proxy/
作者
发布于
2025-04-28
许可协议
CC BY-NC-SA 4.0