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

使用ConditionalHeaders与HttpCache插件的Ktor二次请求未返回304 NOT MODIFIED

Ktor ConditionalHeaders 返回200而非304的问题修复

问题现象

服务端安装ConditionalHeaders插件生成ETag,客户端配置内存型HttpCache插件。首次请求返回正确的ETag头,后续请求也携带了预期的If-None-Match头,但服务端始终返回200 OK而非预期的304 Not Modified。调试确认EntityTagVersion.check(..)返回VersionCheckResult.NOT_MODIFIED,但响应状态未被正确修改。

问题原因

核心原因是**ConditionalHeaders插件的安装位置错误**:将插件安装在路由(route)内部时,其拦截器的执行顺序可能滞后于路由响应逻辑,导致无法在响应发送前替换状态码为304。

解决方案

将ConditionalHeaders插件移至应用级别(application代码块内)安装,确保其拦截器能在所有路由响应发送前执行条件检查并修改响应。

修改后的测试用例代码:

@Test
fun testIfNoneMatchConditionAcceptedAlt(): Unit = testApplication {

    val client = createClient {
        install(HttpCache)
    }

    val text = """the answer is 42"""

    application {
        // 将ConditionalHeaders移至应用级别安装
        install(ConditionalHeaders) {
            version { _, outgoingContent ->
                if (outgoingContent is TextContent) {
                    listOf(EntityTagVersion(etag = outgoingContent.text.encodeBase64(), weak = false))
                } else emptyList()
            }
        }
        routing {
            route("a") {
                get("b") {
                    call.respond(HttpStatusCode.OK, text)
                }
            }
        }
    }

    val first = client.get("a/b")
    assertEquals(expected = text.encodeBase64().quote(), actual = first.etag())
    assertEquals(HttpStatusCode.OK, first.status)
    assertEquals(text, first.bodyAsText())

    val second = client.get("a/b")
    assertEquals(expected = first.etag(), actual = second.request.headers[HttpHeaders.IfNoneMatch])
    assertEquals(HttpStatusCode.NotModified, second.status)
    assertEquals("", second.bodyAsText())
}

补充说明

  • ConditionalHeaders插件的拦截器运行在请求处理的Send阶段,只有安装在应用级别,才能确保所有路由的响应都经过其条件检查逻辑。
  • 无需修改ETag生成逻辑,原代码中基于文本内容生成Base64格式ETag的方式是正确的,插件会自动处理引号封装与匹配校验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 17:43:12