您好,我计划使用 Cloudflare cdn-cgi 跟踪服务来获取客户端 IP 和用户代理结果。如果我获取此链接:
https://www.cloudflare.com/cdn-cgi/trace
,我得到的结果是文本格式。
结果文本示例:
fl=47f54
h=www.cloudflare.com
ip=11.111.11.11
ts=1597428248.652
visit_scheme=https
uag=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
colo=OH
http=http/2
loc=US
tls=TLSv1.3
sni=plaintext
warp=off
我做了一些研究并发现我需要使用正则表达式?但不知道如何从结果中仅提取 ip 和 uag。
...
ip=11.111.11.11
...
uag=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
...
如何从我获取的每个结果的上述文本中提取结果
11.111.11.11
(所有客户端的 IP 更改)和 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
(所有客户端的 uag 或用户代理更改)?
转换成JSON然后访问怎么样?
const cloudflareFallbackURLs = ['https://one.one.one.one/cdn-cgi/trace',
'https://1.0.0.1/cdn-cgi/trace',
'https://cloudflare-dns.com/cdn-cgi/trace',
'https://cloudflare-eth.com/cdn-cgi/trace',
'https://cloudflare-ipfs.com/cdn-cgi/trace',
'https://workers.dev/cdn-cgi/trace',
'https://pages.dev/cdn-cgi/trace',
'https://cloudflare.tv/cdn-cgi/trace']
async function getCloudflareJSON(){
let data = await fetchWithFallback(cloudflareFallbackURLs).then(res=>res.text())
let arr = data.trim().split('\n').map(e=>e.split('='))
return Object.fromEntries(arr)
}
async function fetchWithFallback(links, obj) {
let response;
for (let link of links) {
try {
response = await fetch(link, obj)
if (response.ok)
return response
} catch (e) { }
}
return response
}
getCloudflareJSON().then(console.log)
输出:
{fl: "202f225", h: "1.1.1.1", ip: "47.37.137.777", ts: "1625581799.09", visit_scheme: "https", …}
参考: 链接1
您可以尝试:
^(?:ip|uag)=(.*)$
上述正则表达式的解释:
^, $
- 分别代表行的开始和结束。(?:ip|uag)
- 表示字面上匹配 ip
或 uag
的非捕获组。=
- 字面上代表 =
。(.*)
- 表示第一个匹配任何零次或多次的捕获组,前面有 ip=
或 uag=
。您可以在这里找到上述正则表达式的演示。
const myRegexp = /^(?:ip|uag)=(.*)$/gm;
const myString = `fl=47f54
h=www.cloudflare.com
ip=11.111.11.11
ts=1597428248.652
visit_scheme=https
uag=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
colo=OH
http=http/2
loc=US
tls=TLSv1.3
sni=plaintext
warp=off`;
let match;
let resultString = "";
match = myRegexp.exec(myString);
while (match != null) {
resultString = resultString.concat(match[1] + "\n");
match = myRegexp.exec(myString);
}
console.log(resultString);
第二种方法:
const myString = `fl=47f54
h=www.cloudflare.com
ip=11.111.11.11
ts=1597428248.652
visit_scheme=https
uag=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
colo=OH
http=http/2
loc=US
tls=TLSv1.3
sni=plaintext
warp=off`;
// Split on new line filter on the condition that element starts with ip or uag and join
console.log(myString.split("\n").filter(el => el.startsWith("ip") || el.startsWith("uag")).join('\n'));
我尝试了这个,它成功了
fetch('https://www.cloudflare.com/cdn-cgi/trace')
.then(response => response.text())
.then(data => console.log(data.match(/ip=(\S+)/)[1]));
我在对象数组中制作了这个纯文本数据,逻辑如下: `
const data = `fl=47f54
h=www.cloudflare.com
ip=11.111.11.11
ts=1597428248.652
visit_scheme=https
uag=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
colo=OH
http=http/2
loc=US
tls=TLSv1.3
sni=plaintext
warp=off`;
data.split('\n').map((item)=>{
let b = {};
const c = item.split('=');
b[c[0]]=c[1]
return b;
})
`