使用javascript获取Cloudflare的HTTP_CF_IPCOUNTRY标头?

Bad*_*ari 6 javascript web-worker geoip cloudflare

有很多SO问题如何使用javascript获取http标头,但由于某种原因,它们不会显示HTTP_CF_IPCOUNTRY标头.

如果我尝试使用php echo $_SERVER["HTTP_CF_IPCOUNTRY"];,它可以工作,所以CF工作得很好.

是否可以使用javascript获取此标头?

Faw*_*med 9

/cdn-cgi/trace您可以从 cloudflares端点获取国家/地区代码等

async function getCloudflareJSON(){
let data = await fetch('https://1.1.1.1/cdn-cgi/trace').then(res=>res.text())
let arr = data.trim().split('\n').map(e=>e.split('='))
return Object.fromEntries(arr)
}

getCloudflareJSON().then(console.log)
Run Code Online (Sandbox Code Playgroud)


Don*_*ndi 7

@Quentin 的回答是正确的,对于任何试图访问服务器标头的 javascript 客户端都适用。

但是,由于这个问题特定于 Cloudlfare,并且特定于在 HTTP_CF_IPCOUNTRY 标头中正常获取 2 个字母的国家/地区 ISO,因此我相信我有一个最适合所提出问题的解决方法。

下面是我在前端 Ember App上使用的代码摘录,位于 Cloudflare 后面......和清漆......和快速启动......

function parseTrace(url){
    let trace = [];
    $.ajax(url,
        {
            success: function(response){
                let lines = response.split('\n');
                let keyValue;

                lines.forEach(function(line){
                    keyValue = line.split('=');
                    trace[keyValue[0]] = decodeURIComponent(keyValue[1] || '');

                    if(keyValue[0] === 'loc' && trace['loc'] !== 'XX'){
                        alert(trace['loc']);
                    }

                    if(keyValue[0] === 'ip'){
                        alert(trace['ip']);
                    }

                });

                return trace;
            },
            error: function(){
                return trace;
            }
        }
    );
};

let cfTrace = parseTrace('/cdn-cgi/trace');
Run Code Online (Sandbox Code Playgroud)

性能真的很棒,即使在调用其他 API 或函数之前也不要害怕调用此函数。我发现它与从 Cloudflare 的缓存中检索静态资源一样快,有时甚至更快。您可以在 Pingdom 上运行配置文件来确认这一点。


Sim*_*ver 6

是的,您必须访问服务器 - 但它不一定是您的服务器。

我有一个购物车,其中几乎所有内容都由 Cloudflare 缓存 - 所以我觉得去我的服务器只获取国家/地区代码是愚蠢的。

相反,我在 Cloudflare 上使用网络工作者(额外收费):

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

async function handleRequest(request) {
  
  var countryCode = request.headers.get('CF-IPCountry');
  
  return new Response(
    
    JSON.stringify({ countryCode }),

    { headers: {
      "Content-Type": "application/json"
    }});
}
Run Code Online (Sandbox Code Playgroud)

您可以将此脚本映射到一个路由,例如/api/countrycode,然后当您的客户端发出 HTTP 请求时,它基本上会立即返回(对我来说大约是 10 毫秒)。

 /api/countrycode
 {
    "countryCode": "US"
 }
Run Code Online (Sandbox Code Playgroud)

一些额外的事情:

  • 您不能在所有服务级别上使用网络工作者
  • 最好在与备份相同的 URL 上部署实际的 Web 服务(如果 Webworkers 未启用或支持或在开发过程中)
  • 有费用但应该可以忽略不计
  • 似乎有一个新功能可以将单个路径映射到单个脚本。这就是我在这里所做的。我认为这曾经是企业独有的功能,但现在我可以使用它,所以这很棒。
  • 不要忘记它可能是 TOR 网络的 T1

自从我写这篇文章以来,他们已经公开了更多的房产Request.cf- 即使是价格较低的计划:

https://developers.cloudflare.com/workers/runtime-apis/request#incomingrequestcfproperties

您现在可以获取cityregion甚至longitudelatitude,而无需使用地理查找数据库。


Que*_*tin 5

假设您正在谈论客户端JavaScript:不,这是不可能的.

  1. 浏览器向服务器发出HTTP请求.
  2. 服务器会注意到请求来自哪个IP地址
  3. 服务器在数据库中查找该IP地址并查找匹配的国家/地区
  4. 服务器将该国家/地区传递给PHP

数据甚至都不会靠近浏览器.

要让JavaScript访问它,您需要使用服务器端代码读取它,然后将其放回到浏览器的响应中.