通过CF-Workers免费部署获取IP和地理位置
PS:由于奈斯猫nsmao的免费key用不了导致小板报失效,所以自己部署了一个。
缺点:中国大陆IP的位置获取没有nasmao那么精准....
右边是小板报效果。

准备工作:
1:cloudflare账号
2:托管在cloudflare的域名
创建Workers
1:登录cloudflare找到Workers 路由---管理Workers--创建应用程序,选择从Hello World!开始

2:名称随便填,点击部署。完成后点击编辑代码,把默认的代码全部清空,复制下面的IP位置代码全部粘贴进去,完后重新点击部署。
const CACHE_TTL = 86400; // Worker 边缘缓存 1 天
const TIMEOUT_MS = 1000; // ip-api 最多等待 1 秒
const CACHE_VERSION = "v3";
function browserHeaders() {
return {
"content-type": "application/json;charset=UTF-8",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type",
"Cache-Control": "no-store, no-cache, must-revalidate, max-age=0",
"Pragma": "no-cache",
"Expires": "0"
};
}
function edgeCacheHeaders() {
return {
"content-type": "application/json;charset=UTF-8",
"Cache-Control": `public, max-age=${CACHE_TTL}`
};
}
async function fetchWithTimeout(url, timeoutMs) {
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), timeoutMs);
try {
return await fetch(url, {
signal: controller.signal,
headers: {
"User-Agent": "Mozilla/5.0"
}
});
} finally {
clearTimeout(timer);
}
}
function makeBrowserResponse(body) {
return new Response(body, {
headers: browserHeaders()
});
}
export default {
async fetch(request, env, ctx) {
if (request.method === "OPTIONS") {
return new Response(null, {
status: 204,
headers: browserHeaders()
});
}
const clientIp =
request.headers.get("cf-connecting-ip") ||
request.headers.get("x-forwarded-for")?.split(",")[0]?.trim() ||
"";
if (!clientIp) {
const body = JSON.stringify({
status: "fail",
code: 400,
data: {
ip: "",
country: "未知",
prov: "",
city: "",
district: "",
lat: 0,
lng: 0
}
});
return new Response(body, {
status: 400,
headers: browserHeaders()
});
}
const cache = caches.default;
// 注意:缓存 key 里包含 IP,所以不同 IP 不会共用缓存
const cacheKey = new Request(
`https://ip-cache.local/${encodeURIComponent(clientIp)}?v=${CACHE_VERSION}`,
{ method: "GET" }
);
const cached = await cache.match(cacheKey);
if (cached) {
const cachedBody = await cached.text();
// 这里不能直接 return cached,
// 否则浏览器又会缓存旧结果
return makeBrowserResponse(cachedBody);
}
let result;
try {
const ipApiRes = await fetchWithTimeout(
`http://ip-api.com/json/${encodeURIComponent(clientIp)}?lang=zh-CN`,
TIMEOUT_MS
);
const d = await ipApiRes.json();
result = {
status: "success",
code: 200,
data: {
ip: clientIp,
country: d.country || "中国",
prov: d.regionName || "",
city: d.city || "",
district: d.district || "",
lat: d.lat || 0,
lng: d.lon || 0
}
};
} catch (e) {
const cf = request.cf || {};
result = {
status: "success",
code: 200,
data: {
ip: clientIp,
country: cf.country || "中国",
prov: cf.region || "",
city: cf.city || "",
district: "",
lat: cf.latitude ? Number(cf.latitude) : 0,
lng: cf.longitude ? Number(cf.longitude) : 0
}
};
}
const body = JSON.stringify(result);
// 存进 Worker 边缘缓存
const edgeResponse = new Response(body, {
headers: edgeCacheHeaders()
});
ctx.waitUntil(cache.put(cacheKey, edgeResponse.clone()));
// 返回给浏览器时禁止浏览器缓存
return makeBrowserResponse(body);
}
};3:部署成功后,点击设置--添加域--自定义域,输入自己喜欢的二级域名,完成后直接输入域名就可以返回IP信息了。
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果
-topaz-denoise-enhance-tuya.jpg)
