Skip to content

提供静态内容

无论您是创建网站还是 HTTP 端点,您的应用程序都可能需要提供文件,例如样式表、脚本或图片。 虽然 Ktor 确实可以加载文件内容并将其在响应中发送给客户端,但 Ktor 通过提供额外的函数来简化此过程,以便提供静态内容。

借助 Ktor,您可以从文件夹ZIP 文件嵌入式应用程序资源中提供内容。

文件夹

要从本地文件系统提供静态文件,请使用 staticFiles() 函数。在此情况下,相对路径将使用当前工作目录进行解析。

kotlin
routing {
    staticFiles("/resources", File("files"))
}

在上面的示例中,来自 /resources 的任何请求都映射到当前工作目录中的 files 物理文件夹。 只要 URL 路径和物理文件名匹配,Ktor 就会递归地提供 files 中的任何文件。

关于完整示例,请参见 static-files

ZIP 文件

要从 ZIP 文件提供静态内容,Ktor 提供了 staticZip() 函数。这允许您将请求直接映射到 ZIP 归档的内容,如下例所示:

kotlin
routing {
    staticZip("/", "", Paths.get("files/text-files.zip"))
}

在此示例中,来自根 URL / 的任何请求都直接映射到 ZIP 文件 text-files.zip 的内容。

自动重新加载支持

staticZip() 函数还支持自动重新加载。如果在 ZIP 文件的父目录中检测到任何更改,ZIP 文件系统将在下一个请求时重新加载。这确保了所提供的内容保持最新,而无需服务器重新启动。

关于完整示例,请参见 static-zip

资源

要从 classpath 提供内容,请使用 staticResources() 函数。

kotlin
routing {
    staticResources("/resources", "static")
}

这会将来自 /resources 的任何请求映射到应用程序资源中的 static 包。 在此情况下,只要 URL 路径和资源路径匹配,Ktor 就会递归地提供 static 包中的任何文件。

关于完整示例,请参见 static-resources

附加配置

Ktor 为静态文件和资源提供了更多配置。

索引文件

如果存在名为 index.html 的文件,Ktor 默认会在请求目录时提供该文件。您可以使用 index 参数设置自定义索引文件:

kotlin
staticResources("/custom", "static", index = "custom_index.html")

在此情况下,当请求 /custom 时,Ktor 将提供 /custom_index.html

预压缩文件

Ktor 提供了提供预压缩文件的能力,并避免使用动态压缩。要使用此功能性,请在代码块语句中定义 preCompressed() 函数:

kotlin
staticFiles("/", File("files")) {
    preCompressed(CompressedFileType.BROTLI, CompressedFileType.GZIP)
}

在此示例中,对于对 /js/script.js 发出的请求,Ktor 可以提供 /js/script.js.br/js/script.js.gz

HEAD 请求

enableAutoHeadResponse() 函数允许您自动响应静态路由内定义了 GET 的每个路径的 HEAD 请求。

kotlin
staticResources("/", "static"){
    enableAutoHeadResponse()
}

默认文件响应

default() 函数提供了在静态路由中没有相应文件时,用文件回复任何请求的能力。

kotlin
staticFiles("/", File("files")) {
    default("index.html")
}

在此示例中,当客户端请求不存在的资源时,index.html 文件将作为响应提供。

内容类型

默认情况下,Ktor 会尝试从文件扩展名猜测 Content-Type 标头的值。您可以使用 contentType() 函数显式设置 Content-Type 标头。

kotlin
staticFiles("/files", File("textFiles")) {
    contentType { file ->
        when (file.name) {
            "html-file.txt" -> ContentType.Text.Html
            else -> null
        }
    }
}

在此示例中,文件 html-file.txt 的响应将包含 Content-Type: text/html 标头,对于其他所有文件,将应用默认行为。

缓存

cacheControl() 函数允许您配置 HTTP 缓存的 Cache-Control 标头。

kotlin
fun Application.module() {
    routing {
        staticFiles("/files", File("textFiles")) {
            cacheControl { file ->
                when (file.name) {
                    "file.txt" -> listOf(Immutable, CacheControl.MaxAge(10000))
                    else -> emptyList()
                }
            }
        }
    }
}
object Immutable : CacheControl(null) {
    override fun toString(): String = "immutable"
}

关于 Ktor 中缓存的更多信息,请参见 Caching headers

排除文件

exclude() 函数允许您排除文件不被提供。当客户端请求被排除的文件时,服务器将以 403 Forbidden 状态码响应。

kotlin
staticFiles("/files", File("textFiles")) {
    exclude { file -> file.path.contains("excluded") }
}

文件扩展名回退

当请求的文件未找到时,Ktor 可以将给定的扩展名添加到文件名并进行搜索。

kotlin
staticResources("/", "static"){
    extensions("html", "htm")
}

在此示例中,当请求 /index 时,Ktor 将搜索 /index.html 并提供找到的内容。

自定义修改

modify() 函数允许您对结果响应应用自定义修改。

kotlin
staticFiles("/", File("files")) {
    modify { file, call ->
        call.response.headers.append(HttpHeaders.ETag, file.name.toString())
    }
}

错误处理

如果请求的内容未找到,Ktor 将自动以 404 Not Found HTTP 状态码响应。

要了解如何配置错误处理,请参见 Status Pages