简体   繁体   English

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

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

I read this question but it didn't answer my question.我读了这个问题,但它没有回答我的问题。

To me Headers and Parameters are both dictionaries with the difference that headers is [String : String] while Parameters is [String : AnyObject]?对我来说,标题和参数都是字典,不同之处在于标题是[String : String]而参数是[String : AnyObject]? and so if your parameters are also Strings then you could send them within the headers (while using a 'x-' prefix to signify they aren't standard headers) which is a common but not good practice.因此,如果您的参数也是字符串,那么您可以在标题中发送它们(同时使用“x-”前缀表示它们不是标准标题),这是一种常见但不是好的做法。

  • Is that correct?那是对的吗?
  • Are there other difference between headers and parameters ? headersparameters之间还有其他区别吗?
  • What kind of other non-String types would you be sending using parameters ?您将使用parameters发送什么样的其他非字符串类型?

Alamofire Request method 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
        )
    }

As an example I have seen people passing ["x-ios-version" : UIDevice.currentDevice().systemVersion] or build versions through headers例如,我看到人们通过["x-ios-version" : UIDevice.currentDevice().systemVersion]或通过标头构建版本

The accepted answer is very practical.公认的答案非常实用。 Make sure you see it.确保你看到它。 But there are two foundational differences I will discuss in depth:但是我将深入讨论两个基本差异:

Where header and parameters are placed in an HTTP Request标头和参数放置在 HTTP 请求中的位置

A URL is different from an HTTP Message. URL 不同于 HTTP 消息。 An HTTP Message can either be a Request or a Response . HTTP 消息可以是RequestResponse In this answer I will focus on the request.在这个答案中,我将专注于请求。

An HTTP Request is made up of mainly the url, http-method, http-headers (there are other chunks in it, but I'm just mentioning the ones we care about the most)一个 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

A request line is:请求行是:

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

CLRF is something like a new line. CLRF就像一条新线。

For more see 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如果您真的想深入了解,请参阅此RFC

So basically a request is something like:所以基本上一个请求是这样的:

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

The query params are within the URL. 查询参数在 URL 中。 HTTP Headers are NOT part of the URL. HTTP 标头不是 URL 的一部分。 They're part of the HTTP Message.它们是 HTTP 消息的一部分。 In the above example, query params is tag=networking&order=newest , the headers are:在上面的例子中,查询参数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

So when you make a network request, you're making a string formatted using the http protocol.因此,当您发出网络请求时,您正在制作一个使用 http 协议格式化的字符串。 That string is sent through a TCP connection该字符串是通过 TCP 连接发送的

2 - Why and where one is preferred over the other 2 - 为什么以及在哪里优先于另一个

From discussion with Rob in chat:来自与 Rob 在聊天中的讨论:

The criteria is that if it's information about the request or about the client , then the header is appropriate.标准是,如果它是关于请求或关于客户端的信息,那么标头是合适的。
But if it's the content of the request itself (eg what you are requesting from the server, some details that identify the item to be returned, some details to be saved on the web server, etc.), then it's a parameter eg:但如果它是请求本身的内容(例如,您从服务器请求的内容、标识要返回的项目的一些详细信息、要保存在 Web 服务器上的一些详细信息等),那么它就是一个参数,例如:

Parameter范围
Let's say you're requesting an image for a product.假设您正在请求产品的图像。 The product id may be one parameter.产品id可以是一个参数。 The image size (thumbnail vs full size) might be another parameter.图像大小(缩略图与全尺寸)可能是另一个参数。 The product id and requested image size are examples of "some detail" (or parameter) being supplied as part of the content of a request.产品 ID 和请求的图像大小是作为请求内容的一部分提供的“某些细节”(或参数)的示例。

Header标题
But things like the request is JSON or x-www-form-urlencoded are not the content of the request, but meta data about the request (especially since it's necessary for web service to know how to parse the body of the request).但是请求是 JSON 或x-www-form-urlencoded之类的东西不是请求的内容,而是关于请求的元数据(特别是因为 Web 服务需要知道如何解析请求的正文)。 That's why it's a header.这就是为什么它是一个标题。

Most likely if your app makes various requests, its headers would have a lot in common.如果您的应用程序发出各种请求,最有可能的是,它的标头会有很多共同点。 However the parameters due to the fact that they are content based should be more varied.但是,由于它们是基于内容的,因此参数应该更加多样化。


Construction using URLComponents使用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
        }
    }
}

Here is the list of differences:以下是差异列表:

  1. They are designed for different purposes.它们是为不同的目的而设计的。 Headers carry meta info, parameters carry actual data.标头携带元信息,参数携带实际数据。

  2. HTTP Servers will automatically un-escape/decode parameter names/values. HTTP 服务器将自动取消转义/解码参数名称/值。 This does not apply to header names/values.这不适用于标头名称/值。

  3. Header names/values need to be manually escaped/encoded at client side and be manually un-escaped/decoded at server side.标头名称/值需要在客户端手动转义/编码,并在服务器端手动取消转义/解码。 Base64 encoding or percent escape is often used.经常使用 Base64 编码或百分比转义。

  4. Parameters can be seen by end-users (in URL), but headers are hidden to end-users.最终用户可以看到参数(在 URL 中),但标题对最终用户是隐藏的。

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

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