如何通过Vapor Client或async-http获取重定向后的最终响应URL?
在Vapor中获取重定向后的最终URL
解决思路
Vapor默认Client会自动跟随重定向,但响应对象未直接封装最终访问URL。需要通过自定义重定向处理逻辑,在每次重定向时从响应头中提取目标地址,逐步记录最终的实际访问URL。
实现方法
方法1:基于Vapor Client自定义重定向回调
通过配置Client的redirectConfiguration,在重定向触发时更新记录的URL:
import Vapor func fetchFinalURL(from initialURL: URL) async throws -> String { var finalURL: URL = initialURL let app = Application(.development) defer { app.shutdown() } // 发起请求并配置重定向处理 _ = try await app.client.get(initialURL) { request in request.redirectConfiguration = .follow(with: { response, _ in // 从Location响应头解析重定向目标URL if let locationStr = response.headers.first(name: .location), let redirectURL = URL(string: locationStr, relativeTo: finalURL) { finalURL = redirectURL.absoluteURL } return true // 返回true表示继续跟随后续重定向 }) } return finalURL.absoluteString } // 使用示例 if let initialURL = URL(string: "http://website.com") { do { let resultURL = try await fetchFinalURL(from: initialURL) print("最终访问URL:\(resultURL)") } catch { print("请求错误:\(error.localizedDescription)") } }
方法2:直接使用底层async-http-client库
Vapor Client基于async-http-client,可以直接操作该库手动追踪重定向:
import AsyncHTTPClient func fetchFinalURLWithAsyncHTTP(from initialURL: URL) async throws -> String { let httpClient = HTTPClient(eventLoopGroupProvider: .createNew) defer { try? httpClient.syncShutdown() } var currentURL: URL = initialURL var needFollow = true while needFollow { // 禁用自动重定向,手动处理 let response = try await httpClient.get(url: currentURL, followRedirects: false) if let locationStr = response.headers.first(name: .location), let redirectURL = URL(string: locationStr, relativeTo: currentURL) { currentURL = redirectURL.absoluteURL } else { needFollow = false } } return currentURL.absoluteString } // 使用示例 if let initialURL = URL(string: "http://website.com") { do { let resultURL = try await fetchFinalURLWithAsyncHTTP(from: initialURL) print("最终访问URL:\(resultURL)") } catch { print("请求错误:\(error.localizedDescription)") } }
说明
两种方式的核心逻辑一致:通过解析重定向响应的Location头,逐步更新当前访问的URL,直到没有后续重定向为止。方法1适配Vapor框架生态,方法2适合需要更底层网络控制的场景。
内容的提问来源于stack exchange,提问作者Graham
相关产品推荐
相关产品推荐

