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

如何让Android Retrofit的GET请求强制返回HTTPS响应?

问题

在个人Android应用中对接openexchangerates.org的API,使用两个接口:

  • https://openexchangerates.org/api/currencies.json
  • https://openexchangerates.org/api/latest.json

调用currencies.json请求正常,日志如下:

0001 https://openexchangerates.org/currencies.json
0001 0.001 callStart
--> GET https://openexchangerates.org/currencies.json
Accept: application/json
--> END GET
0001 0.010 proxySelectStart
0001 0.011 proxySelectEnd
0001 0.012 dnsStart
0001 0.052 dnsEnd
0001 0.061 connectStart
0001 0.174 secureConnectStart
0001 0.658 secureConnectEnd
0001 0.660 connectEnd
0001 0.661 connectionAcquired
0001 0.663 requestHeadersStart
0001 0.664 requestHeadersEnd
0001 0.864 responseHeadersStart
0001 0.864 responseHeadersEnd
0001 0.866 responseBodyStart
0001 0.867 responseBodyEnd
0001 0.871 requestHeadersStart
0001 0.872 requestHeadersEnd
0001 0.984 responseHeadersStart
0001 0.984 responseHeadersEnd
<-- 200 OK https://openexchangerates.org/api/currencies.json (982ms)
Access-Control-Allow-Origin: *
Cache-Control: public
Content-Type: application/json; charset=utf-8
Date: Wed, 27 Dec 2023 13:04:55 GMT
Last-Modified: Thu, 23 Dec 2021 13:45:36 GMT
Server: nginx/1.12.2
Vary: Accept-Encoding
Connection: keep-alive
0001 0.988 responseBodyStart
0001 0.988 responseBodyEnd
{
  "AED": "United Arab Emirates Dirham",
  "AFN": "Afghan Afghani",
  "ALL": "Albanian Lek",

但调用latest.json时出现异常:请求目标是HTTPS端点,响应却跳转到HTTP地址,日志如下:

0002 https://openexchangerates.org/latest.json?app_id=sdfgsdfgsdgsdfgsdgsdgsdgsdgsdgsdgsdg
0002 0.000 callStart
--> GET https://openexchangerates.org/latest.json?app_id=sdfgsdfgsdgsdfgsdgsdgsdgsdgsdgsdgsdg
Accept: application/json
--> END GET
0002 0.003 connectionAcquired
0002 0.004 requestHeadersStart
0002 0.005 requestHeadersEnd
0002 0.008 responseFailed
0002 0.010 connectionReleased
0002 0.011 connectStart
0002 0.142 secureConnectStart
0002 0.554 secureConnectEnd
0002 0.555 connectEnd
0002 0.555 connectionAcquired
0002 0.556 requestHeadersStart
0002 0.558 requestHeadersEnd
0002 0.962 responseHeadersStart
0002 0.963 responseHeadersEnd
0002 0.964 responseBodyStart
0002 0.965 responseBodyEnd
0002 0.968 connectionReleased
0002 0.969 proxySelectStart
0002 0.970 proxySelectEnd
0002 0.971 dnsStart
0002 0.992 dnsEnd
0002 0.994 connectStart
0002 1.110 connectEnd
0002 1.111 connectionAcquired
0002 1.112 requestHeadersStart
0002 1.114 requestHeadersEnd
0002 1.224 responseHeadersStart
0002 1.225 responseHeadersEnd
<-- 200 OK http://openexchangerates.org/api/latest.json?app_id=sdfgsdfgsdgsdfgsdgsdgsdgsdgsdgsdgsdg (1224ms)
Access-Control-Allow-Origin: *
Cache-Control: public
Content-Type: application/json; charset=utf-8
Date: Wed, 27 Dec 2023 13:07:34 GMT
Etag: W/"3c46229cfde06a956ce1b6198e484341"
Last-Modified: Wed, 27 Dec 2023 13:00:00 GMT
Server: nginx/1.12.2
Vary: Accept-Encoding
Connection: keep-alive
0002 1.229 responseBodyStart
0002 1.230 responseBodyEnd

配置Retrofit禁止跟随重定向后,返回301响应,Location指向HTTP地址:

0002 https://openexchangerates.org/latest.json?app_id=sdfgsdfgsdgsdfgsdgsdgsdgsdgsdgsdgsdg
0002 0.000 callStart
--> GET https://openexchangerates.org/latest.json?app_id=sdfgsdfgsdgsdfgsdgsdgsdgsdgsdgsdgsdg
Accept: application/json
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36
--> END GET
0002 0.002 connectionAcquired
0002 0.003 requestHeadersStart
0002 0.004 requestHeadersEnd
0002 0.155 responseHeadersStart
0002 0.156 responseHeadersEnd
0002 0.157 responseBodyStart
0002 0.157 responseBodyEnd
<-- 301 Moved Permanently https://openexchangerates.org/latest.json?app_id=sdfgsdfgsdgsdfgsdgsdgsdgsdgsdgsdgsdg (157ms)
Content-Type: text/html; charset=utf-8
Date: Wed, 27 Dec 2023 14:19:31 GMT
Location: http://openexchangerates.org/api/latest.json?app_id=sdfgsdfgsdgsdfgsdgsdgsdgsdgsdgsdgsdg
Referrer-Policy: strict-origin-when-cross-origin
Server: nginx/1.12.2
Strict-Transport-Security: max-age=2592000
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Powered-By: PHP/5.5.9-1ubuntu4.21
Content-Length: 0
Connection: keep-alive
<-- END HTTP (0-byte body)
0002 0.161 connectionReleased
0002 0.161 callEnd

请问为何目标是HTTPS端点却返回HTTP响应?有什么方法可以修正该问题?


原因分析

  1. 请求路径错误:调用latest.json时使用的URL是https://openexchangerates.org/latest.json,缺少了正确的/api/前缀(和currencies.json的标准路径一致),触发了服务器的301永久重定向。
  2. 服务器配置问题:服务器返回的重定向Location头错误地使用了HTTP协议,尽管返回了HSTS头强制HTTPS,但自身重定向逻辑未正确生成HTTPS目标地址。

解决方法

1. 修正请求URL(推荐)

直接使用包含/api/前缀的正确HTTPS路径:https://openexchangerates.org/api/latest.json,从根源避免重定向触发,这是最简洁可靠的方案。

2. 拦截重定向并修正协议

如果无法修改请求URL,可在OkHttp(Retrofit底层依赖)中添加拦截器,自动将Location中的HTTP替换为HTTPS:

val redirectInterceptor = Interceptor { chain ->
    val originalResponse = chain.proceed(chain.request())
    val location = originalResponse.header("Location")
    
    if (originalResponse.isRedirect && location?.startsWith("http://") == true) {
        val secureLocation = location.replaceFirst("http://", "https://")
        originalResponse.newBuilder()
            .header("Location", secureLocation)
            .build()
    } else {
        originalResponse
    }
}

val okHttpClient = OkHttpClient.Builder()
    .addInterceptor(redirectInterceptor)
    .build()

val retrofit = Retrofit.Builder()
    .baseUrl("https://openexchangerates.org/")
    .client(okHttpClient)
    .addConverterFactory(GsonConverterFactory.create())
    .build()

3. 强制仅使用HTTPS连接

配置OkHttp的ConnectionSpec,拒绝HTTP连接,防止意外的HTTP跳转带来的安全风险:

val secureSpec = ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
    .allEnabledCipherSuites()
    .allEnabledTlsVersions()
    .build()

val okHttpClient = OkHttpClient.Builder()
    .connectionSpecs(listOf(secureSpec))
    .build()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 08:44:55