Vapor技术问题:如何为路由分配多个域名?
在Vapor中托管多个域名的实现方法
当然可行!Vapor虽然官方文档没把这个做成单独的教程章节,但实际上通过两种常用方式就能轻松实现多域名托管,下面给你详细说明:
方案一:用路由组直接绑定域名
这种方式最直观,适合路由划分清晰的场景——Vapor的路由组支持通过host方法指定该组下的所有路由只响应特定域名的请求:
// 绑定example.com及其www子域名的路由组 let exampleDomainRoutes = app.grouped(host: ["example.com", "www.example.com"]) exampleDomainRoutes.get { request in return "欢迎访问Example.com的首页!" } exampleDomainRoutes.get("about") { request in return "这是Example.com的关于页面" } // 绑定another-domain.com的路由组 let anotherDomainRoutes = app.grouped(host: ["another-domain.com", "www.another-domain.com"]) anotherDomainRoutes.get { request in return "Welcome to Another Domain!" } anotherDomainRoutes.get("services") { request in return "Our service list for Another Domain" } // 可选:通用路由,匹配所有未指定域名的请求 app.get("common") { request in return "这个页面所有域名都能访问" }
方案二:用中间件统一处理域名逻辑
如果需要对域名做更复杂的判断(比如动态域名、权限校验),可以写一个自定义中间件来解析主机名,再把域名信息传递给后续路由:
import Vapor struct DomainCheckMiddleware: AsyncMiddleware { func respond(to request: Request, chainingTo next: AsyncResponder) async throws -> Response { guard let host = request.headers.host else { throw Abort(.badRequest, reason: "缺少主机头信息") } // 把当前域名存入请求的存储区,方便后续路由/控制器读取 switch host { case "example.com", "www.example.com": request.storage.set(DomainIdentifierKey.self, to: "example") case "another-domain.com", "www.another-domain.com": request.storage.set(DomainIdentifierKey.self, to: "another") default: // 对未知域名返回404或重定向 throw Abort(.notFound, reason: "当前域名不被支持") } return try await next.respond(to: request) } } // 定义存储域名标识的Key private struct DomainIdentifierKey: StorageKey { typealias Value = String }
然后在configure.swift里注册这个中间件:
app.middleware.use(DomainCheckMiddleware())
之后就能在路由里读取域名信息做差异化处理了:
app.get { request in guard let domainId = request.storage.get(DomainIdentifierKey.self) else { return "无法识别当前域名" } return "你正在访问的是\(domainId)站点" }
部署注意事项
- 确保服务器(不管是Vapor自带的HTTPServer还是Nginx反向代理)配置了所有域名的SSL证书,推荐用通配符证书覆盖所有子域名
- 所有域名的DNS解析都要指向你的服务器IP
- 如果用反向代理,一定要配置转发
Host头,否则Vapor拿不到正确的请求主机名
内容的提问来源于stack exchange,提问作者RickardTF
相关产品推荐
相关产品推荐

