You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GET请求浏览器正常,Postman超时后遭Cloudflare拦截问题

解决Cloudflare拦截Postman重复调用API的问题

问题描述

我在调用API https://api.btcxindia.com/ticker/ 时遇到了奇怪的拦截问题:

  • 首次用Postman调用能正常拿到返回结果(状态码200)
  • 保持Postman打开10分钟后再次调用,返回Cloudflare的503拦截页面,页面内容如下:
<!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" /> <meta name="robots" content="noindex, nofollow" /> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" /> <title>Just a moment...</title> <style type="text/css"> html, body {width: 100%; height: 100%; margin: 0; padding: 0;} body {background-color: #ffffff; font-family: Helvetica, Arial, sans-serif; font-size: 100%;} h1 {font-size: 1.5em; color: #404040; text-align: center;} p {font-size: 1em; color: #404040; text-align: center; margin: 10px 0 0 0;} #spinner {margin: 0 auto 30px auto; display: block;} .attribution {margin-top: 20px;} @-webkit-keyframes bubbles { 33%: { -webkit-transform: translateY(10px); transform: translateY(10px); } 66% { -webkit-transform: translateY(-10px); transform: translateY(-10px); } 100% { -webkit-transform: translateY(0); transform: translateY(0); } } @keyframes bubbles { 33%: { -webkit-transform: translateY(10px); transform: translateY(10px); } 66% { -webkit-transform: translateY(-10px); transform: translateY(-10px); } 100% { -webkit-transform: translateY(0); transform: translateY(0); } } .bubbles { background-color: #404040; width:15px; height: 15px; margin:2px; border-radius:100%; -webkit-animation:bubbles 0.6s 0.07s infinite ease-in-out; animation:bubbles 0.6s 0.07s infinite ease-in-out; -webkit-animation-fill-mode:both; animation-fill-mode:both; display:inline-block; } </style> <script type="text/javascript"> // <![CDATA[ (function(){ var a = function() {try{return !!window.addEventListener} catch(e) {return !1} }, b = function(b, c) {a() ? document.addEventListener("DOMContentLoaded", b, c) : document.attachEvent("onreadystatechange", b)}; b(function(){ var a = document.getElementById('cf-content');a.style.display = 'block'; setTimeout(function(){ var s,t,o,p,b,r,e,a,k,i,n,g,f, zHvFeWz={"vFQLFVZTSM":+((!+[]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]))}; t = document.createElement('div'); t.innerHTML="<a href='/'>x</a>"; t = t.firstChild.href;r = t.match(/https?:///)[0]; t = t.substr(r.length); t = t.substr(0,t.length-1); a = document.getElementById('jschl-answer'); f = document.getElementById('challenge-form'); ;zHvFeWz.vFQLFVZTSM+=+((+!![]+[])+(+!![]));zHvFeWz.vFQLFVZTSM-=+((!+[]+!![]+[])+(+!![]));zHvFeWz.vFQLFVZTSM*=+((!+[]+!![]+[])+(+!![]));zHvFeWz.vFQLFVZTSM+=+((!+[]+!![]+!![]+!![]+[])+(+!![]));zHvFeWz.vFQLFVZTSM*=+((!+[]+!![]+!![]+!![]+[])+(+[]));zHvFeWz.vFQLFVZTSM*=+((!+[]+!![]+!![]+!![]+[])+(+!![]));zHvFeWz.vFQLFVZTSM+=+((+!![]+[])+(!+[]+!![]));zHvFeWz.vFQLFVZTSM+=+((!+[]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]));a.value = parseInt(zHvFeWz.vFQLFVZTSM, 10) + t.length; '; 121' f.action += location.hash; f.submit(); }, 4000); }, false); })(); //]]> </script> </head> <body> <table width="100%" height="100%" cellpadding="20"> <tr> <td align="center" valign="middle"> <div class="cf-browser-verification cf-im-under-attack"> <noscript> <h1 data-translate="turn_on_js" style="color:#bd2426;">Please turn JavaScript on and reload the page.</h1> </noscript> <div id="cf-content" style="display:none"> <div> <div class="bubbles"></div> <div class="bubbles"></div> <div class="bubbles"></div> </div> <h1> <span data-translate="checking_browser">Checking your browser before accessing</span> btcxindia.com. </h1> <p data-translate="process_is_automatic">This process is automatic. Your browser will redirect to your requested content shortly.</p> <p data-translate="allow_5_secs">Please allow up to 5 seconds&hellip;</p> </div> <form id="challenge-form" action="/cdn-cgi/l/chk_jschl" method="get"> <input type="hidden" name="jschl_vc" value="dbc7ac6d545de8521a2a3f24574a78a4"/> <input type="hidden" name="pass" value="1516515065.895-rdlkMQJ0RT"/> <input type="hidden" id="jschl-answer" name="jschl_answer"/> </form> </div> <div class="attribution"> <a href="https://www.cloudflare.com/5xx-error-landing?utm_source=iuam" target="_blank" style="font-size: 12px;">DDoS protection by Cloudflare</a> <br> Ray ID: 3e081d20db788866 </div> </td> </tr> </table> </body> </html>
  • 同样的API在浏览器中多次调用完全正常,没有被拦截。

补充的请求头信息:

  • 首次成功请求的响应头:
alternate-protocol →443:spdy/3.1
cache-control →no-store, no-cache
cf-ray →3e19a7fc98652f11-DEL
content-encoding →gzip
content-type →application/json
date →Tue, 23 Jan 2018 09:16:48 GMT
expect-ct →max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
expires →0
pragma →no-cache
server →cloudflare
status →200
strict-transport-security →max-age=31536000
vary →Accept-Encoding
  • 超时后失败请求的响应头:
cache-control →no-cache
cf-ray →3e19afdd4f322f11-DEL
content-type →text/html; charset=UTF-8
date →Tue, 23 Jan 2018 09:22:10 GMT
expect-ct →max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
server →cloudflare
status →503
x-frame-options →SAMEORIGIN

问题分析

这个问题的核心是Cloudflare的浏览器验证机制在搞事情。为什么浏览器没问题但Postman会被拦截?原因很明确:

  1. Cloudflare会根据请求的特征(比如User-Agent、Cookie、会话行为)判断请求是否来自“正常浏览器”。浏览器会自动处理Cookie的更新、执行Cloudflare的JavaScript验证逻辑,而Postman作为API工具,默认不会自动处理这些动态验证步骤。
  2. 首次请求时,Cloudflare给你颁发了会话Cookie,但10分钟后会话过期,Postman没有自动触发Cloudflare的JS验证流程来刷新会话,所以被判定为可疑请求,返回503拦截页面。

解决方案

这里有几个可行的办法,按优先级排序:

1. 模拟浏览器的请求特征

在Postman中配置请求,让它更像真实浏览器的请求:

  • 设置正确的User-Agent:从你的浏览器复制User-Agent字符串(比如Chrome的是Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36),添加到Postman的请求头里。
  • 启用自动保存Cookie:在Postman的设置中开启“Automatically send cookies”,确保会话Cookie被持续维护。
  • 手动处理Cloudflare验证(临时方案):如果还是被拦截,把浏览器中成功请求的Cookie复制到Postman的请求头里,替换掉旧的Cookie,一般能恢复访问。

2. 使用Postman的Interceptor插件

Postman的Interceptor可以直接捕获浏览器的请求,包括所有的Cookie和请求头,然后导入到Postman中。这样你的请求就完全和浏览器一致,Cloudflare就不会拦截了。步骤大概是:

  • 安装Postman Interceptor浏览器插件和Postman客户端的Interceptor扩展
  • 开启拦截功能,在浏览器中调用一次API,然后把捕获的请求导入到Postman,之后用这个导入的请求调用API即可。

3. 编写脚本自动处理Cloudflare验证(进阶)

如果需要长期自动化调用,可以写脚本(比如Python的requests配合cloudscraper库)来自动处理Cloudflare的JS验证。cloudscraper会模拟浏览器执行Cloudflare的验证逻辑,自动获取有效的会话Cookie。示例代码大概是:

import cloudscraper

scraper = cloudscraper.create_scraper()
response = scraper.get('https://api.btcxindia.com/ticker/')
print(response.json())

内容的提问来源于stack exchange,提问作者sun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:50:13