使用javascript获取Cloudflare的HTTP_CF_IPCOUNTRY标头?

时间:2015-09-08 10:20:15

标签: javascript cloudflare geoip

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

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

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

5 个答案:

答案 0 :(得分:5)

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

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

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

答案 1 :(得分:3)

@ 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');

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

答案 2 :(得分:0)

我已经采纳了Don Omondi的答案,并将其转换为一个promise函数,以便于使用。

function get_country_code() {
    return new Promise((resolve, reject) => {
        var trace = []; 
        jQuery.ajax('/cdn-cgi/trace', {
            success: function(response) {
                var lines = response.split('\n');
                var keyValue;
                for (var index = 0; index < lines.length; index++) {
                    const line = lines[index];
                    keyValue = line.split('=');
                    trace[keyValue[0]] = decodeURIComponent(keyValue[1] || '');
                    if (keyValue[0] === 'loc' && trace['loc'] !== 'XX') {
                        return resolve(trace['loc']);
                    }
                }
            },
            error: function() {
                return reject(trace);
            }
        });

    });
}

用法示例

get_country_code().then((country_code) => {
    // do something with the variable country_code
}).catch((err) => {
    // caught the error, now do something with it
});

答案 3 :(得分:0)

是的,您必须访问服务器-但这不必是您的服务器。

我有一个购物车,其中几乎所有东西都被Cloudflare缓存了-所以我觉得去我的服务器获取国家代码是愚蠢的。

相反,我在Cloudflare上使用了一个Webworker(额外收费):

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"
    }});
}

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

 /api/countrycode
 {
    "countryCode": "US"
 }

加上其他内容:

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

答案 4 :(得分:0)

const isPowerOfTwo = (number) => {
  let result = false;
  for (let i = 1; i <= 6; i++) {
    if (number === Math.pow(2, i)) {
      result = true;
    }
  }
  return result;
};

console.log(isPowerOfTwo(16));
console.log(isPowerOfTwo(10));

参考:

https://cloudflare-quic.com/b

https://cloudflare-quic.com/b/headers

有用的链接:

https://www.cloudflare.com/cdn-cgi/trace

https://github.com/fawazahmed0/cloudflare-trace-api