使用EdgeOne的边缘函数获取用户IP

原本是想用EdgeOne Pages实现 像CloudFlare Pages那样部署一个

后来发现EdgeOne的边缘函数可以搞定 然后就折腾了一下

首先添加域名

进入edgeone控制台 选择已绑定域名

点击添加域名 输入你需要设置的二级域名 回源配置随便填 模板选择 不使用模板

添加完成后等待部署完成 HTTPS配置选择免费证书

 

在等待部署期间 左侧菜单滑动到底部 边缘函数 选择函数管理

新建函数 选第一个 创建Hello World 模板即可 点击下一步

输入函数名称   下面函数代码区域 粘贴函数代码 替换原有的

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request));
});

function handleRequest(request) {
  const url = new URL(request.url);
  const path = url.pathname;
  // 通过 request.eo.clientIp 获取客户端 IP
  const ip = request.eo.clientIp || '';

  if(path==='/'){
    return new Response(ip, {status: 200,headers: {
            "content-type": "text/html;charset=UTF-8",
            }})
  } else if(path==='/json'){
    return new Response(JSON.stringify({ ip }), {
      headers: {
        'content-type': 'application/json',
      },
    });
  } else if(path==='/info') {
    const info = {
      ip,
      geo: request.eo.geo
    }
     return new Response(JSON.stringify({ info }), {
      headers: {
        'content-type': 'application/json',
      },
    });
  } else {
    return new Response("404", {status: 404})
  }
  
}

 

20250905更新
支持cors白名单 设置allowedDomains 就行

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request));
});

function handleRequest(request) {
  const url = new URL(request.url);
  const path = url.pathname;
  const ip = request.eo.clientIp || '';
  const origin = request.headers.get('Origin');

  // ✅ 配置你想要支持的主域名列表(不包含协议和路径)
  const allowedDomains = [
    'lcsoul.cn',
    'localhost',
    '127.0.0.1'
  ];

  // 检查 origin 是否匹配任何一个允许的域名(包括子域名)
  const corsOrigin = isOriginAllowed(origin, allowedDomains) ? origin : null;

  // 处理预检请求 (OPTIONS)
  if (request.method === 'OPTIONS') {
    if (corsOrigin) {
      const headers = {
        'Access-Control-Allow-Origin': corsOrigin,
        'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
        'Access-Control-Allow-Headers': 'Content-Type, Authorization',
        'Access-Control-Max-Age': '86400', // 24小时缓存预检
      };
      return new Response(null, { status: 204, headers });
    }
    return new Response('Forbidden', { status: 403 });
  }

  // 构建实际响应
  let response;

  if (path === '/') {
    response = new Response(`${ip}\n`, {
      status: 200,
      headers: { 'content-type': 'text/html;charset=UTF-8' },
    });
  } else if (path === '/json') {
    response = new Response(JSON.stringify({ ip }), {
      headers: { 'content-type': 'application/json' },
    });
  } else if (path === '/info') {
    const info = {
      ip,
      geo: request.eo.geo,
    };
    response = new Response(JSON.stringify({ info }), {
      headers: { 'content-type': 'application/json' },
    });
  } else {
    response = new Response('404 Not Found', { status: 404 });
  }

  // 添加 CORS 响应头(仅当来源合法)
  if (corsOrigin) {
    response.headers.set('Access-Control-Allow-Origin', corsOrigin);
    response.headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
    response.headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  }

  return response;
}

/**
 * 判断 origin 是否属于允许的域名或其子域名
 * 支持 http:// 和 https://,忽略协议
 */
function isOriginAllowed(origin, allowedDomains) {
  if (!origin || typeof origin !== 'string') return false;

  try {
    const url = new URL(origin); // 自动补全协议处理
    const hostname = url.hostname; // 如:api.example.com

    for (const domain of allowedDomains) {
      // 匹配主域名本身:example.com
      if (hostname === domain) return true;
      // 匹配子域名:*.example.com
      if (hostname.endsWith('.' + domain)) return true;
    }
  } catch (e) {
    return false;
  }

  return false;
}

 

 

点击 创建并保存部署

在部署成功弹窗中 点击新增触发规则

触发条件中填入上面添加的子域名然后确定保存

这时候就可以访问子域名获取访问用户的IP了

 

 

PS:添加域名时选择开启IPv6访问  因网络访问默认IPv6优先 大概率只能获取到v6地址(如果有)

如果需要获取IPv4 可以再添加一个域名 关闭IPv6访问 然后再去边缘函数 触发配置中 在刚添加的规则中添加新增的子域名即可

如果啥也不知道  添加完边缘函数  在列表中点击函数名称 进入详情后点击编辑代码

编辑页面右上角有个AI助手 可以让AI帮你写(有坑自行注意)

 

 

 

获取访问IP(支持IPv6)

获取访问IP(仅IPv4)

参考文档:

获取客户端IP

阅读剩余
THE END