惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

W
WeLiveSecurity
T
Tenable Blog
Project Zero
Project Zero
C
Cybersecurity and Infrastructure Security Agency CISA
T
The Exploit Database - CXSecurity.com
P
Palo Alto Networks Blog
S
Schneier on Security
Scott Helme
Scott Helme
S
Securelist
Know Your Adversary
Know Your Adversary
Vercel News
Vercel News
IT之家
IT之家
V
V2EX
F
Fortinet All Blogs
Simon Willison's Weblog
Simon Willison's Weblog
K
Kaspersky official blog
博客园_首页
T
Tailwind CSS Blog
The GitHub Blog
The GitHub Blog
Spread Privacy
Spread Privacy
Microsoft Security Blog
Microsoft Security Blog
Cisco Talos Blog
Cisco Talos Blog
The Register - Security
The Register - Security
有赞技术团队
有赞技术团队
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Cyberwarzone
Cyberwarzone
Google DeepMind News
Google DeepMind News
The Hacker News
The Hacker News
L
LINUX DO - 热门话题
Hugging Face - Blog
Hugging Face - Blog
博客园 - 三生石上(FineUI控件)
A
Arctic Wolf
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
C
CXSECURITY Database RSS Feed - CXSecurity.com
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
T
Threat Research - Cisco Blogs
P
Proofpoint News Feed
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
P
Privacy & Cybersecurity Law Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
CERT Recently Published Vulnerability Notes
S
SegmentFault 最新的问题
AWS News Blog
AWS News Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
罗磊的独立博客
Apple Machine Learning Research
Apple Machine Learning Research
P
Proofpoint News Feed
The Cloudflare Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Vulnerabilities – Threatpost

HikariLan's Blog

把 LLM 当成“人”,才是 Agent 工程进阶的起点 | HikariLan’s Blog 为什么我认为 AI 正在让初级技术岗位完全消失 | HikariLan’s Blog 感谢款待!日本东京 & 富士山游记 | HikariLan’s Blog 你的 RAG 系统可能正在“杀死”大模型的灵性 | HikariLan’s Blog 只有开始工作的那一刻,成年之旅才正式开始(22岁生日总结) | HikariLan’s Blog 学长,我得休息了,明天要面软*动力 | HikariLan’s Blog EdgeOne 边缘函数重定向跟随导致 WordPress 无法正常登录 —— 问题排查与解决思路 | HikariLan’s Blog 香港半日游 + 开户记 | HikariLan’s Blog 谈谈我理解的互联网技术岗校招以及职业选择 | HikariLan’s Blog
利用 EdgeOne 边缘函数写入 Cloudflare IP GeoLocation 回源请求头以支持 WP-Statistics GeoIP | HikariLan’s Blog
2025-09-16 · via HikariLan's Blog

由 AI 生成的文章摘要

通过EdgeOne边缘函数与规则引擎配合,模拟Cloudflare IP Geolocation请求头以支持WP-Statistics插件的GeoIP功能。解决方案包含回源请求头配置和边缘函数代码,额外提供AVIF/WEBP图片格式转换优化方案,提升网页加载性能。

本文最后更新于 236 天前,其中的信息可能已经有所发展或是发生改变。

(标题很长,但这已经是我能想到的最短的叫法了)

前言

昨天群友发来一个 EdgeOne 领取免费版套餐兑换码的链接,竟然是 100% 中奖,每周 2000 份(截止到现在也就兑了 350 份,基本是随便送了),一直很想把现有的国内腾讯云 CDN、国外 Cloudflare 的方案迁移到 EdgeOne 上,但奈何一直领不到免费版兑换码,这次终于如愿,遂赶紧噼里啪啦配置一顿,工作良好。

基本功能配置完毕,看了下 EdgeOne 有哪些额外功能,注意到 EdgeOne 支持携带客户端 IP 的地理位置信息回源,这让我想起来 Cloudflare 有一个名为 IP GeoLocation 的玩意儿,做了同样的事情,会把用户的国家码注入到 CF-IPCountry 请求头上给下游用(当然 EdgeOne 这里默认名称是 EO-Client-IPCountry)。

这让我想起来我的 WP-Statistics 插件也支持 Cloudflare IP GeoLocation 作为位置检测方法,于是探索了一下怎么让 EO 支持这套东西。本来以为简单配配规则引擎上的回源请求头就行了,结果完全没这么简单... 兜兜转转整了一天,终于探索出一套解决方案,遂分享出来(绝对不是水博客!)

解决方案

此方案也适用于其他需要在 EdgeOne 上使用 Cloudflare IP GeoLocation 同款请求头的需求。

首先,根据 WP-Statistics 源代码中的 CloudflareGeolocationProvider,可以看到 WP-Statistics 通过 isAvailableisBehindCloudflare 两个函数判断是否可以使用 Cloudflare IP GeoLocation 作为位置检测方式 —— 后者是初步判断,只有满足后者才能在设置中启用 IP GeoLocation;前者是最终判断,如果这个不为 true,即使你启用了 IP GeoLocation,也会被 fallback 到 MaxMind GeoIP 数据库的查询模式。

因此,取此二者函数所需要的请求头的并集,就得到了我们需要在 EO 上配置的回源请求头列表:

  • HTTP_CF_CONNECTING_IP
  • HTTP_CF_IPCOUNTRY
  • HTTP_CF_IPCONTINENT
  • HTTP_CF_REGION
  • HTTP_CF_IPCITY
  • HTTP_CF_IPLATITUDE
  • HTTP_CF_IPLONGITUDE
  • HTTP_CF_POSTAL_CODE

他们分别反映了访问者的连接 IP、所在国家、大洲、地区/州省、城市、经纬度、邮政编码(我不知道为什么他需要这个,而且事实上 EO 也提供不了这个,所以最后 Mock 了一个默认值)

但是很遗憾的是,EdgeOne 当前的规则引擎系统不支持配置地区和经纬度,所以这部分会交由边缘函数来做(别问我为什么边缘函数支持但是规则引擎不支持,另外也别问我为什么不全放到边缘函数上,规则引擎支持的大洲信息到边缘函数这儿又不支持了)。

于是,我们首先在规则引擎上配置如下修改回源请求头规则:

CF-IPCity: ${http.request.ip.city}
CF-IPCountry: ${http.request.ip.country}
CF-IPContinent: ${http.request.ip.continent}
CF-Connecting-IP: ${http.request.ip}

然后,在 EdgeOne 边缘函数上配置如下代码:

async function handleRequest(event) {
  const { request } = event;

  const headers = new Headers(request.headers);

  // 修改请求头
  headers.set('cf-iplongitude', request.eo.geo.longitude);
  headers.set('cf-iplatitude', request.eo.geo.latitude);
  headers.set('cf-region', request.eo.geo.regionName);
  headers.set('cf-region-code', request.eo.geo.regionCode);
  headers.set('cf-postal-code', '000000');

  const response = await fetch(new Request(request.url, {
      method: request.method,
      headers: headers,
      body: request.body,
      redirect: 'manual' // 二编:这里一定要是 manual,不然会使用默认的 follow 导致重定向跟随丢失上下文
    }));
  return response;
}

addEventListener('fetch', event => {
  // 当函数代码抛出未处理的异常时,边缘函数会将此请求转发回源站 
  event.passThroughOnException();
  event.respondWith(handleRequest(event));
});

配置好边缘函数的触发规则后应该就可以正常运行了。最后,注意边缘函数免费版是有用量限制的,小心被用爆。

后记:边缘函数很好玩,顺带做了个 AVIF 转换器

这功能挺好的,直接贴代码,如果用户浏览器支持 avif 就会转换成 avif,不支持就转换成 webp,否则就不转(注意配置完后记得限定触发规则为仅当文件后缀为 jpg, jpeg, png, webp 时才触发,避免浪费):

async function handleEvent(event) {
  const { request } = event;

  // 获取客户端支持的图片类型
  const accept = request.headers.get('Accept');
  const option = { eo: { image: {} } };

  // 检查客户端是否支持 WebP 格式的图片,若不支持响应原图
  if (accept && accept.includes('image/webp')) {
    option.eo.image.format = 'webp';
  }

  // 支持 Avif 优先走 Avif
  if (accept && accept.includes('image/avif')) {
    option.eo.image.format = 'avif';
  }

  const response = await fetch(request, option);
  return response;
}

addEventListener('fetch', event => {
  // 当函数代码抛出未处理的异常时,边缘函数会将此请求转发回源站 
  event.passThroughOnException();
  event.respondWith(handleEvent(event));
});

配置好了以后网页访问速度有肉眼可见的提升,Lighthouse 的 Performance 分数也高了些,针不戳。

扫码关注 HikariLan's Blog 微信公众号,及时获取最新博文!

微信公众号图片