HTTP参数和HTTPheaders有什么区别?

What is the difference between HTTP parameters and HTTP headers?

我阅读了 this 问题,但它没有回答我的问题。

对我来说 Headers 和 Parameters 都是字典,区别在于 headers 是 [String : String] 而 Parameters 是 [String : AnyObject]? 所以如果你的参数也是字符串那么你可以 在 headers 内发送它们(同时使用 'x-' 前缀表示它们不是标准的 headers)这是常见但不好的实践。

Alamofire Request 方法

public func request(
        method: Method,
        _ URLString: URLStringConvertible,
          parameters: [String: AnyObject]? = nil,
          encoding: ParameterEncoding = .URL,
          headers: [String: String]? = nil)
        -> Request
    {
        return Manager.sharedInstance.request(
            method,
            URLString,
            parameters: parameters,
            encoding: encoding,
            headers: headers
        )
    }

例如,我看到人们通过 ["x-ios-version" : UIDevice.currentDevice().systemVersion] 或通过 headers

构建版本

差异列表如下:

  1. 它们是为不同的目的而设计的。 Headers携带元信息,参数携带实际数据。

  2. HTTP 服务器将自动 un-escape/decode 参数 names/values。这不适用于 header names/values.

  3. Header names/values需要在客户端手动escaped/encoded,在服务器端手动un-escaped/decoded。经常使用Base64编码或者百分号转义。

  4. 参数可以被end-users看到(在URL),但是header被隐藏到end-users.

接受的答案很实用。确保你看到它。但是我将深入讨论两个基本差异:

其中 header 和参数放在 HTTP 请求中

A URL 不同于 HTTP 消息。 HTTP 消息可以是 RequestResponse。在这个答案中,我将重点关注请求。

一个HTTP请求主要由、url、http-method、http-headers组成(其中还有其他块,但是我只是提到我们最关心的)

Request       = Request-Line              ; Section 5.1
                *(( general-header        ; Section 4.5
                  | request-header         ; Section 5.3
                  | entity-header ) CRLF)  ; Section 7.1
                CRLF
                [ message-body ]          ; Section 4.3

请求行是:

Request-Line   = Method SP Request-URI SP HTTP-Version CRLF

CLRF 有点像换行。

有关更多信息,请参阅 here and here. You might have to do some back and forth between the links til you get it right. If you really wanted to go deep then see see this RFC

所以基本上一个请求是这样的:

POST /cgi-bin/process.cgi?tag=networking&order=newest HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)
Host: www.tutorialspoint.com
Content-Type: text/xml; charset=utf-8
Content-Length: 60
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: Keep-Alive

first=Zara&last=Ali

query params 个在 URL 个之内。 HTTP Header 不是 URL 的一部分。它们是 HTTP 消息的一部分。在上面的例子中,query paramstag=networking&order=newest,header是:

User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)
Host: www.tutorialspoint.com
Content-Type: text/xml; charset=utf-8
Content-Length: 60
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: Keep-Alive

因此,当您发出网络请求时,您发出的是一个使用 http 协议格式化的字符串。该字符串通过 TCP 连接发送

2 - 为什么以及在哪里比另一个更受青睐

来自与 Rob 在聊天中的讨论:

标准是,如果它是关于请求或关于客户端的信息,那么header是合适的。
但是,如果它是请求本身的 content(例如,您从服务器请求的内容、一些标识要返回的项目的详细信息、一些要保存在 Web 服务器上的详细信息等) .),那么它就是一个参数,例如:

参数
假设您正在请求产品的图片。产品id可以是一个参数。图像大小(缩略图与完整大小)可能是另一个参数。 产品 ID 和请求的图像大小是作为请求内容的一部分提供的“一些细节”(或参数)的示例。

Header
但是请求是 JSON 或 x-www-form-urlencoded 之类的东西不是请求的 content,而是关于 request 的元数据](特别是因为 Web 服务有必要知道如何解析请求的 body)。这就是为什么它是 header.

如果您的应用发出各种请求,很可能它的 header 会有很多共同点。然而,由于它们是基于内容的,因此参数应该更加多样化。


施工使用URLComponents

class UnsplashRequester {
    
    static let session = URLSession.shared
    static let host = "api.unsplash.com"
    static let photosPath = "/photos"
    static let accessKey = "My_access_key"
    
    static func imageRequester(pageValue: String, completion: @escaping (Data?) -> Void) {
        var components = URLComponents()
        components.scheme = "https"
        components.host = host
        components.path = photosPath

        // A: Adding a Query Parameter to a URL
        components.queryItems = [URLQueryItem(name: "page", value: pageValue)]
        let headers: [String: String] = ["Authorization": "Client-ID \(accessKey)"]
        
        var request = URLRequest(url: components.url!)
        for header in headers {
            
            // B: Adding a Header to a URL
            request.addValue(header.value, forHTTPHeaderField: header.key)
        }
        
        let task = session.dataTask(with: request) { data, _, error in
        }
    }
}