绕过 Google AI 区域限制:Cloudflare 代理方案详解
CloudflareProxyGemini

绕过 Google AI 区域限制:Cloudflare 代理方案详解

Google AI Studio 提供了 Gemini 等模型的 API 访问,但存在地域限制。文章介绍了如何通过 Cloudflare Workers 和 Durable Objects 构建代理服务来绕过此限制。核心思路是利用 Durable Objects 的地域选择特性,将请求转发到支持 Google AI API 的地区,并通过 Workers 作为流量入口实现透明代理。项目已开源,并提供了可用的代理服务。

114次点击3分钟阅读

Google AI Studio 提供 Google 最新模型的尝鲜,例如 gemini-flash-2.0-exp 多模态模型,提供了模型内置的图像创作和编辑能力。这些模型可以通过 API 方式调用,个人用户有可观的免费额度。

然而,Google AI API 目前存在地域限制,仅对特定地区开放服务。

地域限制问题

Google AI API 目前主要在以下地区提供服务:

  • 北美(美国、加拿大)
  • 欧洲部分地区
  • 澳大利亚等

这导致其他地区的开发者在访问 API 时会遇到限制。要绕开这些限制,除了自购买和部署代理服务外,还可以考虑使用 Cloudflare 的 Workers 服务。

CloudFlare 代理解决方案

通过 CloudFlare 的 Workers 和 Durable Objects,我们可以构建一个稳定可靠的代理服务来解决地域限制问题。核心实现思路如下:

1. 利用 Durable Objects 的地域选择特性

Durable Objects 允许我们指定实例的运行地域,这是解决方案的关键所在。我们可以:

  • 将 Durable Object 实例设置在支持 Google AI API 的地区(如美国西部)
  • 确保 API 请求从合适的地理位置发出

下面代码示例 DurableObject 通过 fetch 发送中转 API 请求。

TypeScript
import { DurableObject } from "cloudflare:workers";

/**
 * Env provides a mechanism to reference bindings declared in wrangler.jsonc within JavaScript
 *
 * @typedef {Object} Env
 * @property {DurableObjectNamespace} MY_DURABLE_OBJECT - The Durable Object namespace binding
 */

/** A Durable Object's behavior is defined in an exported Javascript class */
export class GeminiProxy extends DurableObject {
	/**
	 * The constructor is invoked once upon creation of the Durable Object, i.e. the first call to
	 * 	`DurableObjectStub::get` for a given identifier (no-op constructors can be omitted)
	 *
	 * @param {DurableObjectState} ctx - The interface for interacting with Durable Object state
	 * @param {Env} env - The interface to reference bindings declared in wrangler.jsonc
	 */
	constructor(ctx, env) {
		super(ctx, env);
	}

	async fetch(req) {
		return fetch(req);
	}

	async sayHello() {
		return {
			status: 200,
			body: "Hello from Durable Object!",
		}
	}
}

2. Workers 作为流量入口

CloudFlare Workers 作为全球分布的边缘计算服务,可以:

  • 接收来自全球各地的 API 请求
  • 将请求转发至指定地区的 Durable Object 实例
  • 实现请求的透明代理

下面的代码示例 Worker 如何中转用户请求至 DurableObject,同时在自动创建 DurableObject 实例时指定地域。

TypeScript
export default {
  async fetch(request, env) {
    const url = new URL(request.url);

    // 添加跨域支持
    let corsHeaders = {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Methods": "GET,HEAD,POST,OPTIONS",
      "Access-Control-Allow-Headers": request.headers.get(
        "Access-Control-Request-Headers"
      ),
    };

    // 如果是预检请求,直接返回跨域头
    if (request.method === "OPTIONS") {
      return new Response(null, { headers: corsHeaders });
    }

		if (url.pathname === "/") {
      return new Response("Hello", {
        status: 200,
      });
    }

		const id = env.MY_DURABLE_OBJECT.idFromName("gemini");

		// 指定地域美国西部
		const stub = env.MY_DURABLE_OBJECT.get(id, { locationHint: "wnam" });

		if (url.pathname === "/hello") {
			const result = await stub.sayHello();
			return new Response(JSON.stringify(result), {
				status: result.status,
			});
		}


		let targetURL = new URL("https://generativelanguage.googleapis.com");

    targetURL.pathname = url.pathname;
    targetURL.search = url.search;

		let newRequest = new Request(targetURL, {
      method: request.method,
      headers: request.headers,
      body: request.body,
    });

		let response = await stub.fetch(newRequest);

    // 复制响应以添加新的头
    let responseHeaders = new Headers(response.headers);
    for (let [key, value] of Object.entries(corsHeaders)) {
      responseHeaders.set(key, value);
    }

    return new Response(response.body, {
      status: response.status,
      statusText: response.statusText,
      headers: responseHeaders,
    });
  },
};

完整可部署工程

项目已开源在Github,可直接 fork 并修改相关配置实现部署,请注意 DurableObject 需要 Cloudflare 付费计划订阅才可使用($5/月起),如果不想开通付费计划,也可以直接使用我提供的代理服务 https://gemini.aiuuuu.com