使用 javascript 获取 Cloudflare 的 HTTP_CF_IPCOUNTRY header?
Get Cloudflare's HTTP_CF_IPCOUNTRY header with javascript?
有很多关于如何使用 javascript 获取 http headers 的问题,但由于某些原因,它们没有出现 HTTP_CF_IPCOUNTRY header。
如果我尝试使用 php echo $_SERVER["HTTP_CF_IPCOUNTRY"];
,它可以工作,所以 CF 工作正常。
是否可以用 javascript 得到这个 header?
假设您在谈论客户端JavaScript:不,这是不可能的。
- 浏览器向服务器发出 HTTP 请求。
- 服务器注意到请求来自哪个 IP 地址
- 服务器在数据库中查找该 IP 地址并找到匹配的国家/地区
- 服务器将该国家/地区传递给 PHP
数据甚至不会靠近浏览器。
为了 JavaScript 访问它,您需要使用服务器端代码读取它,然后将其放入对浏览器的响应中。
@Quentin 的回答是正确的,适用于任何试图访问服务器 header 的 javascript 客户端。
但是,由于这个问题特定于 Cloudlfare,并且特定于在 HTTP_CF_IPCOUNTRY header 中正常获取 2 个字母的国家/地区 ISO,我相信我有一个最适合的 work-around问的问题。
下面是我在我的前端 Ember App 上使用的代码摘录,位于 Cloudflare...和清漆...和 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 上的个人资料来确认这一点。
我采纳了 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
});
是的,您必须访问服务器 - 但它不一定是您的服务器。
我有一个购物车,其中几乎所有内容都由 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"
}});
}
您可以将此脚本映射到诸如 /api/countrycode
之类的路由,然后当您的客户端发出 HTTP 请求时,它会 return 基本上立即(对我来说大约是 10 毫秒)。
/api/countrycode
{
"countryCode": "US"
}
另外两件事:
- 您不能在所有服务级别上使用网络工作者
- 最好在与备份相同的 URL 上部署实际的网络服务(如果网络工作者未启用或不支持或在开发期间)
- 有收费但应该可以忽略不计
- 似乎有一项新功能,您可以将单个路径映射到单个脚本。这就是我在这里所做的。我认为这曾经是企业专用功能,但现在我可以使用它,这太棒了。
- 不要忘记它可能是 TOR 网络的 T1
自从我写这篇文章后,他们在 Request.cf
上公开了更多的属性——即使是低价计划:
https://developers.cloudflare.com/workers/runtime-apis/request#incomingrequestcfproperties
您现在可以获得 city
、region
甚至 longitude
和 latitude
,而无需使用地理查找数据库。
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 获取 http headers 的问题,但由于某些原因,它们没有出现 HTTP_CF_IPCOUNTRY header。
如果我尝试使用 php echo $_SERVER["HTTP_CF_IPCOUNTRY"];
,它可以工作,所以 CF 工作正常。
是否可以用 javascript 得到这个 header?
假设您在谈论客户端JavaScript:不,这是不可能的。
- 浏览器向服务器发出 HTTP 请求。
- 服务器注意到请求来自哪个 IP 地址
- 服务器在数据库中查找该 IP 地址并找到匹配的国家/地区
- 服务器将该国家/地区传递给 PHP
数据甚至不会靠近浏览器。
为了 JavaScript 访问它,您需要使用服务器端代码读取它,然后将其放入对浏览器的响应中。
@Quentin 的回答是正确的,适用于任何试图访问服务器 header 的 javascript 客户端。
但是,由于这个问题特定于 Cloudlfare,并且特定于在 HTTP_CF_IPCOUNTRY header 中正常获取 2 个字母的国家/地区 ISO,我相信我有一个最适合的 work-around问的问题。
下面是我在我的前端 Ember App 上使用的代码摘录,位于 Cloudflare...和清漆...和 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 上的个人资料来确认这一点。
我采纳了 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
});
是的,您必须访问服务器 - 但它不一定是您的服务器。
我有一个购物车,其中几乎所有内容都由 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"
}});
}
您可以将此脚本映射到诸如 /api/countrycode
之类的路由,然后当您的客户端发出 HTTP 请求时,它会 return 基本上立即(对我来说大约是 10 毫秒)。
/api/countrycode
{
"countryCode": "US"
}
另外两件事:
- 您不能在所有服务级别上使用网络工作者
- 最好在与备份相同的 URL 上部署实际的网络服务(如果网络工作者未启用或不支持或在开发期间)
- 有收费但应该可以忽略不计
- 似乎有一项新功能,您可以将单个路径映射到单个脚本。这就是我在这里所做的。我认为这曾经是企业专用功能,但现在我可以使用它,这太棒了。
- 不要忘记它可能是 TOR 网络的 T1
自从我写这篇文章后,他们在 Request.cf
上公开了更多的属性——即使是低价计划:
https://developers.cloudflare.com/workers/runtime-apis/request#incomingrequestcfproperties
您现在可以获得 city
、region
甚至 longitude
和 latitude
,而无需使用地理查找数据库。
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
有用链接: