如果我尝试使用php:
echo $_SERVER["HTTP_CF_IPCOUNTRY"];
,它可以工作,所以CF运行正常。是否可能使用JavaScript获取此标头?
echo $_SERVER["HTTP_CF_IPCOUNTRY"];
,它可以工作,所以CF运行正常。@Quentin的回答是正确的,并适用于任何尝试访问服务器头部的javascript客户端。
然而,由于这个问题是特定于Cloudflare的,并且是特定于在HTTP_CF_IPCOUNTRY标头中获取2个字母的国家ISO,我相信我有一个解决方法最适合所提出的问题。
下面是一个代码��录,我在我的前端Ember App上使用,在Cloudflare后面...和varnish...和fastboot...
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上运行一下性能分析来确认这一点。
fetch('https://cloudflare-quic.com/b/headers').then(res=>res.json()).then(data=>{console.log(data.headers['Cf-Ipcountry'])})
参考资料:
https://cloudflare-quic.com/b/headers
有用链接:
假设您讨论的是客户端JavaScript:不,这不可能。
数据甚至从未接近浏览器。
要使JavaScript访问它,您需要使用服务器端代码读取它,然后将其放入回传给浏览器的响应中。
CF_IPCOUNTRY
头中。因此,虽然您的方法是正确的,但步骤2和3应该只说“读取HTTP_CF_IPCOUNTRY头”。如果您尝试仅从IP查找国家,那么这将是一个很大的麻烦,并且可能会随时更改。Cloudflare的头应该更准确。 - Simon_Weaver是的,您需要访问服务器 - 但不一定要访问您自己的服务器。
我有一个购物车,Cloudflare 缓存了几乎所有内容 - 所以我觉得单独为获取国家代码而访问我的服务器是愚蠢的。
相反,我在 Cloudflare 上使用了一个 Web Worker(额外收费):
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"
}
还有几件事情需要注意:
自从我写这篇文章以来,他们已经在更低价格的计划中公开了更多的Request.cf
属性:
https://developers.cloudflare.com/workers/runtime-apis/request#incomingrequestcfproperties
现在,您甚至可以获取city
、region
,甚至是longitude
和latitude
,而无需使用地理位置查找数据库。
我采用了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
});