繁体   English   中英

HTTP 参数和 HTTP 标头有什么区别?

[英]What is the difference between HTTP parameters and HTTP headers?

我读了这个问题,但它没有回答我的问题。

对我来说,标题和参数都是字典,不同之处在于标题是[String : String]而参数是[String : AnyObject]? 因此,如果您的参数也是字符串,那么您可以在标题中发送它们(同时使用“x-”前缀表示它们不是标准标题),这是一种常见但不是好的做法。

  • 那是对的吗?
  • headersparameters之间还有其他区别吗?
  • 您将使用parameters发送什么样的其他非字符串类型?

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]或通过标头构建版本

公认的答案非常实用。 确保你看到它。 但是我将深入讨论两个基本差异:

标头和参数放置在 HTTP 请求中的位置

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就像一条新线。

有关更多信息,请参见此处此处 您可能必须在链接之间来回做一些事情,直到正确为止。 如果您真的想深入了解,请参阅此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

查询参数在 URL 中。 HTTP 标头不是 URL 的一部分。 它们是 HTTP 消息的一部分。 在上面的例子中,查询参数tag=networking&order=newest ,标题是:

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 在聊天中的讨论:

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

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

标题
但是请求是 JSON 或x-www-form-urlencoded之类的东西不是请求的内容,而是关于请求的元数据(特别是因为 Web 服务需要知道如何解析请求的正文)。 这就是为什么它是一个标题。

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


使用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
        }
    }
}

以下是差异列表:

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

  2. HTTP 服务器将自动取消转义/解码参数名称/值。 这不适用于标头名称/值。

  3. 标头名称/值需要在客户端手动转义/编码,并在服务器端手动取消转义/解码。 经常使用 Base64 编码或百分比转义。

  4. 最终用户可以看到参数(在 URL 中),但标题对最终用户是隐藏的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM