<
免费Nanobanana-Pro无限调用API
>

没有上一篇咯
下一篇

利用sketchfab给你的博客文章插入3d模型

免费Nanobanana-Pro无限调用API

基于

https://panel.api.airforce/

https://dash.cloudflare.com/

使用教程:

注册:

https://panel.api.airforce/signup

可获取多个key防止key失效

直接调用(限制1分钟/次且可能调用失败)

curl -X POST https://api.airforce/v1/images/generations \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "nano-banana-pro",
  "prompt": "提示词",
  "n": 1,
  "size": "1024x1024",
  "response_format": "b64_json"
}'

扩展(无限制调用+自动重试)

使用CloudFlare Workers实现无限使用

// 内置多个API Key(直接使用你提供的有效Key)
const API_KEYS = [
  "sk-air-1",
  "sk-air-2",
  "sk-air-3",
// (....可自行添加)
];

// 固定配置
const DEFAULT_CONFIG = {
  model: "nano-banana-pro",
  size: "1024x1024",
  n: 1,
  response_format: "b64_json",
  seed: null
};

// 允许的参数范围
const ALLOWED_MODELS = ["nano-banana-pro"];
const ALLOWED_SIZES = ["256x256", "512x512", "1024x1024", "1024x1792", "1792x1024"];
const MAX_N = 4;

// 自动重试配置
const RETRY_CONFIG = {
  maxRetry: 5,
  retryDelay: 300
};

export default {
  async fetch(request, env, ctx) {
    try {
      // 处理CORS预检
      if (request.method === "OPTIONS") {
        return handleCORS(request);
      }

      // 仅支持POST请求
      if (request.method !== "POST") {
        return new Response(JSON.stringify({
          error: { message: "仅支持POST请求", type: "invalid_request_error" }
        }), {
          status: 405,
          headers: { ...getCORSHeaders(request), "Content-Type": "application/json" },
        });
      }

      // 解析JSON请求体
      let requestBody;
      try {
        requestBody = await request.json();
      } catch (parseError) {
        return new Response(JSON.stringify({
          error: { message: "请求体必须是JSON格式", type: "invalid_request_error", detail: parseError.message }
        }), {
          status: 400,
          headers: { ...getCORSHeaders(request), "Content-Type": "application/json" },
        });
      }

      // 提取并校验参数
      const { prompt, model, size, n, seed } = requestBody;
      if (!prompt || typeof prompt !== "string" || !prompt.trim()) {
        return new Response(JSON.stringify({
          error: { message: "prompt是必填项(字符串格式)", type: "invalid_request_error" }
        }), {
          status: 400,
          headers: { ...getCORSHeaders(request), "Content-Type": "application/json" },
        });
      }

      // 构建最终参数
      const finalParams = {
        prompt: prompt.trim(),
        model: (model?.trim() || DEFAULT_CONFIG.model),
        size: (size?.trim() || DEFAULT_CONFIG.size),
        n: (typeof n === "number" && !isNaN(n)) ? Math.floor(n) : DEFAULT_CONFIG.n,
        response_format: DEFAULT_CONFIG.response_format,
        seed: (typeof seed === "number" && !isNaN(seed)) ? Math.floor(seed) : DEFAULT_CONFIG.seed
      };

      // 验证参数合法性
      const validationError = validateParams(finalParams);
      if (validationError) {
        return new Response(JSON.stringify({
          error: { message: validationError, type: "invalid_request_error" }
        }), {
          status: 400,
          headers: { ...getCORSHeaders(request), "Content-Type": "application/json" },
        });
      }

      // 带重试调用API
      const apiData = await callImageApiWithRetry(finalParams);

      // 验证图片数据
      if (!apiData.data || !apiData.data.length || !apiData.data[0].b64_json) {
        return new Response(JSON.stringify({
          error: { message: `经${RETRY_CONFIG.maxRetry}次重试后未获取到有效图片`, type: "api_error" }
        }), {
          status: 404,
          headers: { ...getCORSHeaders(request), "Content-Type": "application/json" },
        });
      }

      // 解码Base64并返回图片
      let imageBuffer;
      try {
        const cleanBase64 = apiData.data[0].b64_json.replace(/\s/g, "");
        imageBuffer = Uint8Array.from(atob(cleanBase64), c => c.charCodeAt(0));
      } catch (decodeError) {
        return new Response(JSON.stringify({
          error: { message: "图片解码失败", type: "server_error", detail: decodeError.message }
        }), {
          status: 500,
          headers: { ...getCORSHeaders(request), "Content-Type": "application/json" },
        });
      }

      // 返回图片响应(浏览器可直接显示)
      return new Response(imageBuffer, {
        status: 200,
        headers: {
          ...getCORSHeaders(request),
          "Content-Type": "image/png",
          "Cache-Control": "public, max-age=86400",
          "Content-Length": imageBuffer.length.toString(),
        },
      });

    } catch (error) {
      return new Response(JSON.stringify({
        error: { message: "服务器内部错误", type: "server_error", detail: error.message }
      }), {
        status: 500,
        headers: { ...getCORSHeaders(request), "Content-Type": "application/json" },
      });
    }
  },
};

// 带重试的API调用函数
async function callImageApiWithRetry(params) {
  let retryCount = 0;
  let lastError = null;

  while (retryCount < RETRY_CONFIG.maxRetry) {
    try {
      const apiKey = getNextApiKey();
      const apiResponse = await fetch("https://api.airforce/v1/images/generations", {
        method: "POST",
        headers: {
          "Authorization": `Bearer ${apiKey}`,
          "Content-Type": "application/json",
        },
        body: JSON.stringify(params),
      });

      const apiData = await apiResponse.json();
      if (apiResponse.ok && apiData.data && apiData.data[0].b64_json) {
        return apiData;
      }

      lastError = { status: apiResponse.status, message: apiData.error?.message || "无效响应" };
      console.warn(`重试${retryCount + 1}失败:`, lastError);

    } catch (error) {
      lastError = { message: error.message };
      console.warn(`重试${retryCount + 1}异常:`, lastError);
    }

    if (retryCount < RETRY_CONFIG.maxRetry - 1) {
      await new Promise(resolve => setTimeout(resolve, RETRY_CONFIG.retryDelay));
    }
    retryCount++;
  }

  throw new Error(lastError?.message || "重试失败");
}

// CORS处理函数
function handleCORS(request) {
  return new Response(null, { status: 204, headers: getCORSHeaders(request) });
}

// CORS响应头
function getCORSHeaders(request) {
  const origin = request.headers.get("Origin") || "*";
  return {
    "Access-Control-Allow-Origin": origin,
    "Access-Control-Allow-Methods": "POST, OPTIONS",
    "Access-Control-Allow-Headers": "Content-Type, Authorization",
    "Access-Control-Max-Age": "86400",
  };
}

// 参数验证函数
function validateParams(params) {
  if (!ALLOWED_MODELS.includes(params.model)) {
    return `不支持的模型,允许值:${ALLOWED_MODELS.join(", ")}`;
  }
  if (!ALLOWED_SIZES.includes(params.size)) {
    return `不支持的尺寸,允许值:${ALLOWED_SIZES.join(", ")}`;
  }
  if (params.n < 1 || params.n > MAX_N) {
    return `生成数量n必须在1-${MAX_N}之间`;
  }
  if (params.seed !== null && (params.seed < 0 || params.seed > 4294967295)) {
    return "seed必须是0-4294967295之间的整数";
  }
  return null;
}

// API Key轮询函数
let keyIndex = 0;
function getNextApiKey() {
  if (API_KEYS.length === 0) throw new Error("未配置API Key");
  keyIndex = (keyIndex + 1) % API_KEYS.length;
  return API_KEYS[keyIndex];
}

使用方式:

curl -X POST "https://xxx.xx/" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "一只可爱的小猫在阳光下睡觉",
    "model": "nano-banana-pro",
    "size": "1024x1024",
    "seed": 123456,
    "n": 1
  }' --output image.png
Top
Foot