【问题标题】:Respond with Cache headers for images in Ktor响应 Ktor 中图像的缓存标头
【发布时间】:2020-01-18 14:09:33
【问题描述】:

为 Ktor 提供的静态图像发回缓存标头的正确方法是什么?

我有以下 Ktor 设置:

在我的main:

embeddedServer(
        Netty,
        watchPaths = listOf("module"),
        module = Application::module,
        port = if (ENV.env == LOCAL) {
            8080
        } else {
            80
        }
    ).apply {
        start(wait = true)
    }

然后在main之外:

fun Application.module() {
    if (ENV.env != LOCAL) {
        install(ForwardedHeaderSupport)
        install(XForwardedHeaderSupport)
        install(HttpsRedirect)
    }
    install(CachingHeaders) {
        options { outgoingContent ->
            when (outgoingContent.contentType?.withoutParameters()) {
                ContentType.Image.Any -> CachingOptions(CacheControl.MaxAge(maxAgeSeconds = 30 * 24 * 60 * 60))
                else -> null
            }
        }
    }
    install(Compression) {
        gzip {
            priority = 1.0
        }
        deflate {
            priority = 10.0
            minimumSize(1024) // condition
        }
    }

    routing {
        static("/js/") {
            resources("/js/")
        }

        static("/css/") {
            resources("/css/")
        }

        static("/favicons") {
            resources("/favicons/")
        }

        static("/img/") {
            resources("/static/img/")
            resources("/static/images/")
            resources("/background/")
            resources("/logos/")
            resources("/icons/")
        }
    }
}

但是图像返回时没有缓存标头,有什么想法吗?

更新

ContentType.Image.Any 更改为ContentType.Image.JPEG 似乎可行。查看Image的源代码,它似乎映射到ContentType(image, *) 但根本不匹配任何图像类型。

install(CachingHeaders) {
    options { outgoingContent ->
        when (outgoingContent.contentType?.withoutParameters()) {
            ContentType.Image.JPEG -> CachingOptions(
                cacheControl = CacheControl.MaxAge(
                    mustRevalidate = false,
                    maxAgeSeconds = 30 * 24 * 60 * 60,
                    visibility = CacheControl.Visibility.Public
                )
            )
            else -> null
        }
    }
}

同时提交了一个错误: https://github.com/ktorio/ktor/issues/1366

【问题讨论】:

    标签: caching kotlin ktor


    【解决方案1】:

    原来是对* 进行标准的 eqauls 检查,而不是实际的文件类型,所以使用 match 来解决这个问题:

    install(CachingHeaders) {
        options { outgoingContent ->
            if (outgoingContent.contentType?.withoutParameters()?.match(ContentType.Image.Any) == true) {
                CachingOptions(
                    cacheControl = CacheControl.MaxAge(
                        mustRevalidate = false,
                        maxAgeSeconds = 6 * 30 * 24 * 60 * 60,
                        visibility = CacheControl.Visibility.Public
                    )
                )
            } else {
                null
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      您可以使用以下内容按内容类型设置缓存标头:https://ktor.io/servers/features/caching-headers.html

      【讨论】:

      • 就像我在问题中的代码中所做的那样? ContentType.Image.Any -> CachingOptions(CacheControl.MaxAge(maxAgeSeconds = 30 * 24 * 60 * 60))
      猜你喜欢
      • 1970-01-01
      • 2012-04-26
      • 2011-11-25
      • 2021-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-28
      • 2020-10-14
      • 1970-01-01
      相关资源
      最近更新 更多