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

Retrofit拦截器无法获取请求头,@FormUrlEncoded头也缺失?

问题原因与解决方案

你看不到@FormUrlEncoded对应的请求头,核心原因是OkHttp拦截器的执行顺序:

你当前用的是addInterceptor添加应用拦截器,它的执行时机在OkHttp的桥接拦截器(BridgeInterceptor)之前。而@FormUrlEncoded对应的Content-Type: application/x-www-form-urlencoded; charset=UTF-8请求头,是由桥接拦截器根据请求体的MediaType自动添加的——在应用拦截器阶段,这个头还没被注入到请求中,所以你打印headers会看不到,调用toMultimap()自然也是空集合。

两种解决办法

1. 改用网络拦截器

将拦截器添加方式从addInterceptor换成addNetworkInterceptor,这样拦截器会在桥接拦截器之后执行,就能拿到完整的请求头:

OkHttpClient.Builder()
    .cookieJar(SessionCookieJar())
    // 替换成addNetworkInterceptor
    .addNetworkInterceptor { chain ->
        chain.request().also { request ->
            val buffer = Buffer().also { request.body()?.writeTo(it) }
            Log.d(TAG, "Intercepted request:")
            Log.d(TAG, request.headers().toString())
            Log.d(TAG, buffer.readUtf8())
        }.let(chain::proceed)
    }
    .build()

2. 在应用拦截器中直接读取请求体的MediaType

如果必须保留应用拦截器,可以直接从请求体中获取对应的MediaType(这就是后续会被转换成请求头的内容):

.addInterceptor { chain ->
    chain.request().also { request ->
        val buffer = Buffer().also { request.body()?.writeTo(it) }
        Log.d(TAG, "Intercepted request:")
        // 直接打印请求体的MediaType
        request.body()?.contentType()?.let {
            Log.d(TAG, "Content-Type (from body): $it")
        }
        Log.d(TAG, buffer.readUtf8())
    }.let(chain::proceed)
}

需要明确的是:@FormUrlEncoded注解的作用是让Retrofit生成带有正确MediaType的FormBody,而不是直接添加请求头——请求头的添加是OkHttp桥接拦截器的职责,这就是你在当前拦截器中看不到它的原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 20:17:40