使用 Swift URLSession 将 headers 传递给 URL

Passing headers to URL with Swift URLSession

我不想分享实际的 link,因为它可能包含一些私人信息,所以如果它不起作用,请不要感到惊讶。

我有一个 link 看起来像这样:www.somelink.com/stuff/searchmembers?member=John

还有一些我需要通过的headers,比如Login: Admin, Password: Admin

当我使用 this site 时,一切似乎都运行良好,我将 link 放入 GET 并将 headers 放入 key:value 格式并作为结果我得到了所有成员的列表,但是我怎样才能对 URLSession 做同样的事情呢?这是我目前拥有的,但我什么也没得到。我在那里做错了什么?

func getAllMembers(urlString: String) {

    guard let url = URL(string: urlString) else { return }

    var request = URLRequest(url: url)
    request.httpMethod = "GET"
    request.setValue("Admin", forHTTPHeaderField: "Login")
    request.setValue("Admin", forHTTPHeaderField: "Password")
    request.httpBody = "member=John".data(using: .utf8)!


    URLSession.shared.dataTask(with: request) { (data, response, error) in
        print(response)
        print(data)
    }.resume()
}

member=John 是一个 URL 查询参数,不是请求正文的一部分。所以你需要把它添加到 URL 本身。

func getAllMembers(urlString: String) {
    guard let url = URL(string: "\(urlString)?member=John") else { return }

    var request = URLRequest(url: url)
    request.httpMethod = "GET"
    request.setValue("Admin", forHTTPHeaderField: "Login")
    request.setValue("Admin", forHTTPHeaderField: "Password")


    URLSession.shared.dataTask(with: request) { (data, response, error) in
        print(response)
        print(data)
    }.resume()
}

这是你做错了什么:

你的member=John实际上是一个URL查询参数。通常,URL 请求将查询参数作为 URL 字符串本身的一部分,而不是 httpbody。


快速而简单的解决方案:

如果你删除了你就可以开始了

request.httpBody = "member=John".data(using: .utf8)!

而是将整个 "www.somelink.com/stuff/searchmembers?member=John" 传递给您的 getAllMembers(urlString:) 函数。


更好的解决方案:

假设 John 的用户名是 j o h n。你的函数不会超过第一个 guard 因为空格是无效的 URL 字符串字符。

我喜欢使用 URLComponents 因为它省去了处理空格等的麻烦。

下面是我编写函数的方式:

func getJohnMember(urlString: String) {

    //URLComponents to the rescue!
    var urlBuilder = URLComponents(string: urlString)
    urlBuilder?.queryItems = [
        URLQueryItem(name: "member", value: "j o h n")
    ]

    guard let url = urlBuilder?.url else { return }

    var request = URLRequest(url: url)
    request.httpMethod = "GET"
    request.setValue("Admin", forHTTPHeaderField: "Login")
    request.setValue("Admin", forHTTPHeaderField: "Password")


    URLSession.shared.dataTask(with: request) { (data, response, error) in
        print(response)
        print(String(data: data, encoding: .utf8)) //Try this too!
    }.resume()
}

为了清楚起见,我只将 "www.somelink.com/stuff/searchmembers" 传递给第一个参数。

现在,如果我在 guard let 之后 print(url),我会得到

www.somelink.com/stuff/searchmembers?member=j%20o%20h%20n

这样更容易,不是吗?