获取 URL 参数的值

我正在尝试使用 Swift 从一个 URL 获取参数:

http://mysite3994.com?test1=blah&test2=blahblah

如何获得 test1和 test2的值?

82508 次浏览

可以使用下面的代码获取参数

func getQueryStringParameter(url: String, param: String) -> String? {
guard let url = URLComponents(string: url) else { return nil }
return url.queryItems?.first(where: { $0.name == param })?.value
}

调用类似 let test1 = getQueryStringParameter(url, param: "test1")的方法

扩展的其他方法:

extension URL {
public var queryParameters: [String: String]? {
guard
let components = URLComponents(url: self, resolvingAgainstBaseURL: true),
let queryItems = components.queryItems else { return nil }
return queryItems.reduce(into: [String: String]()) { (result, item) in
result[item.name] = item.value
}
}
}

步骤1: 创建 URL 扩展

extension URL {
func valueOf(_ queryParameterName: String) -> String? {
guard let url = URLComponents(string: self.absoluteString) else { return nil }
return url.queryItems?.first(where: { $0.name == queryParameterName })?.value
}
}

步骤2: 如何使用扩展名

let newURL = URL(string: "http://mysite3994.com?test1=blah&test2=blahblah")!


newURL.valueOf("test1") // Output i.e "blah"
newURL.valueOf("test2") // Output i.e "blahblah"

我还做了一个 URL 扩展,但是将查询参数查找放在下标中。

extension URL {
subscript(queryParam:String) -> String? {
guard let url = URLComponents(string: self.absoluteString) else { return nil }
return url.queryItems?.first(where: { $0.name == queryParam })?.value
}
}

Usage:

let url = URL(string: "http://some-website.com/documents/127/?referrer=147&mode=open")!


let referrer = url["referrer"]  // "147"
let mode     = url["mode"]      // "open"

似乎没有现有的答案工作时,链接导致一个网站上创建的角度。这是因为 Angular 的路径通常在所有链接中都包含一个 #(hash)符号,这导致 url.queryItems总是返回 null。

如果链接看起来像这样: http://example.com/path/#/morepath/aaa?test1=blah&test2=blahblah

然后只能从 url.fragment中获得参数。如果在@Matt 的扩展中添加一些额外的解析逻辑,那么一个更通用的代码应该是这样的:

extension URL {
subscript(queryParam: String) -> String? {
guard let url = URLComponents(string: self.absoluteString) else { return nil }
if let parameters = url.queryItems {
return parameters.first(where: { $0.name == queryParam })?.value
} else if let paramPairs = url.fragment?.components(separatedBy: "?").last?.components(separatedBy: "&") {
for pair in paramPairs where pair.contains(queryParam) {
return pair.components(separatedBy: "=").last
}
return nil
} else {
return nil
}
}
}

用法不变:

let url = URL(string: "http://example.com/path/#/morepath/aaa?test1=blah&test2=blahblah")!


let referrer = url["test1"]  // "blah"
let mode     = url["test2"]  // "blahblah"

另一种方法是在 URL 上创建一个扩展以返回组件,然后在[ URLQueryItem ]上创建一个扩展以从 queryItems 检索值。

extension URL {
var components: URLComponents? {
return URLComponents(url: self, resolvingAgainstBaseURL: false)
}
}


extension Array where Iterator.Element == URLQueryItem {
subscript(_ key: String) -> String? {
return first(where: { $0.name == key })?.value
}
}

这个例子可以说明如何使用:

if let urlComponents = URL(string: "http://mysite3994.com?test1=blah&test2=blahblah")?.components,
let test1Value = urlComponents.queryItems?["test1"] {
print(test1Value)
}