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

Android端OkHttp报504 Gateway Timeout错误,iOS端请求同一URL正常

Troubleshooting 504 Gateway Timeout with OkHttp on Android (Works on iOS)

Hey there, let's break down why your OkHttp request is hitting a 504 Gateway Timeout on Android while the same URL works flawlessly on iOS. Here are the most common culprits and actionable fixes to test out:

1. Missing or Mismatched Request Headers

iOS's URLSession automatically adds several default headers (like User-Agent, Accept-Encoding, or Accept-Language) that OkHttp doesn't include by default. Some gateways enforce specific header requirements, and missing these can trigger unexpected timeouts.

Fix: Capture the full request headers from your iOS app (using a tool like Charles Proxy) and replicate them in your OkHttp request. For example:

Request request = new Request.Builder()
    .url(urlStr)
    .post(formBody)
    .addHeader("User-Agent", "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1")
    .addHeader("Accept-Encoding", "gzip, deflate, br")
    .addHeader("Accept-Language", "en-US,en;q=0.9")
    // Add all other headers from your iOS request here
    .build();

2. Timeout Configuration Gaps

While you've set 30-second timeouts for connect/read/write, OkHttp's timeouts are granular—unlike iOS which might use a single total request timeout. A 504 could occur if the total request duration exceeds the gateway's timeout, even if each individual OkHttp timeout hasn't been triggered.

Fix: Add a callTimeout (total request timeout) and enable connection failure retries (gateways sometimes have transient issues):

OkHttpClient client = new OkHttpClient.Builder()
    .connectTimeout(30, TimeUnit.SECONDS)
    .readTimeout(30, TimeUnit.SECONDS)
    .writeTimeout(30, TimeUnit.SECONDS)
    .callTimeout(60, TimeUnit.SECONDS) // Total timeout for the entire request lifecycle
    .retryOnConnectionFailure(true) // Retry transient connection failures
    .build();

3. Network/Proxy Differences

Android devices might be using a system proxy, VPN, or restricted network that iOS isn't connected to. This can cause the request to route through a slow or blocked gateway, leading to a timeout.

Fix: Force OkHttp to bypass any system proxies to rule out this issue:

OkHttpClient client = new OkHttpClient.Builder()
    .proxy(Proxy.NO_PROXY)
    // Keep your existing configurations
    .build();

Also, test the Android device on the exact same network as the iOS device to eliminate network environment variables.

4. Request Body Encoding Mismatch

If your formBody uses different encoding than iOS's request, the gateway might struggle to parse it, leading to a timeout instead of a more explicit error like 400 Bad Request.

Fix: Ensure your form body uses application/x-www-form-urlencoded encoding (the default for FormBody, but double-check) and explicitly encode parameters to match iOS's behavior:

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

FormBody formBody = new FormBody.Builder()
    .addEncoded("param1", URLEncoder.encode("special-value@123", StandardCharsets.UTF_8.name()))
    .addEncoded("param2", URLEncoder.encode("another value", StandardCharsets.UTF_8.name()))
    .build();

5. SSL/TLS Version Incompatibility

Some gateways restrict connections to newer TLS versions (like 1.2 or 1.3). OkHttp's default configuration might include older TLS versions that the gateway rejects, leading to a timeout during the handshake process.

Fix: Force OkHttp to use only modern TLS versions:

import okhttp3.ConnectionSpec;
import okhttp3.TlsVersion;
import java.util.Collections;

ConnectionSpec modernTlsSpec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
    .tlsVersions(TlsVersion.TLS_1_2, TlsVersion.TLS_1_3)
    .build();

OkHttpClient client = new OkHttpClient.Builder()
    .connectionSpecs(Collections.singletonList(modernTlsSpec))
    // Your existing configurations
    .build();

Pro Tip: Compare Requests Side-by-Side

The most reliable way to pinpoint the exact issue is to capture the full request/response flow for both Android and iOS using a proxy tool like Charles or Wireshark. Look for differences in:

  • Request headers
  • Request body format/encoding
  • TLS handshake process
  • Connection establishment time

This will show you exactly what's different between the two requests and help you fix the mismatch quickly.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 07:37:45