現象描述
- 項目重構,複製代碼到新 Module,修改了靜態類中的 API Base URL。
- 調試確認請求發出的 URL 已是新地址。
- 但服務器返回的數據內容仍是舊項目的數據。
核心判斷:大概率是服務端/網絡層問題,非客戶端代碼問題
排查清單 (按可能性排序)
1. 服務器端配置未同步 (最常見)
- Nginx/Apache 反向代理緩存:舊項目域名配置了 `proxy_cache`,新請求命中緩存返回舊內容。
→ 運維清理緩存 `rm -rf /path/to/cache/*` 或配置 `proxy_cache_bypass`。
- 應用服務器未重啟/熱加載失效:Tomcat/Spring Boot 仍運行舊代碼,新部署包未生效。
→ 重啟服務,檢查部署腳本、CI/CD 流程。
- 數據庫未遷移/同步:新項目連的是舊數據庫實例,或數據同步任務失敗。
→ 檢查 JDBC URL、數據同步職能。
- CDN 緩存:靜態資源/接口走 CDN,邊緣節點緩存未刷新。
→ CDN 控制台刷新緩存,或請求帶版本號/時間戳參數繞過 CDN。
2. 客戶端網絡層緩存
- OkHttp/HttpClient 緩存:客戶端啟用了 HTTP 緩存 (`Cache-Control`),命中本地緩存未發起網絡請求。
→ 代碼中禁用緩存:`requestBuilder.cacheControl(CacheControl.FORCE_NETWORK)` 或 `noCache()`。
- WebView 緩存:若用 WebView 加載,需 `webView.clearCache(true)` 並設置 `WebSettings.setCacheMode(WebSettings.LOAD_NO_CACHE)`。
3. 請求參數/簽名未更新導致命中舊邏輯
- 雖然 Base URL 變了,但請求參數、Header、簽名算法仍按舊邏輯生成,服務器按舊版本接口處理返回舊格式數據。
→ 對比新舊接口文檔,確保參數結構、加密方式、版本號 Header (`X-Api-Version`) 完全一致。
4. DNS/代理/VPN 解析異常
- 新域名解析到舊 IP,或代理服務器將請求轉發到舊服務。
→ `ping/newdomain`、`nslookup` 驗證解析 IP;抓包 (Wireshark/Charles) 確認實際請求目標 IP/Host。
快速驗證方法
- 瀏覽器/Postman 直接訪問新 URL:若返回新數據 → 客戶端代碼/緩存問題;若返回舊數據 → **服務端問題** (90% 以上)。
- 抓包分析 (Charles/Fiddler/Wireshark):確認請求行、Header、Body、響應體細節,對比新舊差異。
- 服務端日誌:查看訪問日誌、應用日誌,確認請求是否到達新代碼邏輯、查詢 SQL 是否正確。
客戶端代碼防禦性寫法
// OkHttp 強制不緩存
OkHttpClient client = new OkHttpClient.Builder()
.cacheControl(new CacheControl.Builder().noCache().noStore().build())
.build();
// 或請求級別控制
Request request = new Request.Builder()
.url(newUrl)
.cacheControl(CacheControl.FORCE_NETWORK)
.build();
// 關鍵:給關鍵接口加隨機參數繞過所有緩存
String url = baseUrl + "/api/data?t=" + System.currentTimeMillis();
總結
Android 修改 URL 後返回舊數據,**90% 是服務端緩存 (Nginx/CDN)、應用未重啟、數據庫未同步** 導致。客戶端優先驗證瀏覽器/Postman 直連新 URL,若仍舊則找後端/運維;若瀏覽器正常則檢查客戶端 HTTP 緩存、WebView 緩存、參數簽名。抓包是定界關鍵。