美文网首页
3.4.3 头信息操作进阶

3.4.3 头信息操作进阶

作者: spbreak | 来源:发表于2016-02-24 16:02 被阅读125次

    1. 添加请求头

    setAllHTTPHeaderFields: 方法提供了一种方式以通过一次调用替换掉所有的请求头.

    addValue:forHTTPHeaderField: 将头逐个添加到请求中

    NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
    [req addValue:@"en" forHTTPHeaderField:@"Content-Language"];
    [req addValue:@"da" forHTTPHeaderField:@"Content-Language"];

    HTTP 协议规定头的名字要以冒号结束, 不过如果省略的话, 该方法会附加一个冒号. 如果相同的头名被添加多次, 那么头的值就是多个值的拼接并使用逗号分隔. 在上述示例中, 最后生成的头如下所示:

    Content-Langeuage: en,da

    2. 删除请求头

    比如, 如果应用想要禁用对返回数据的压缩, 那么可以覆写默认的 iOS 头(默认的头支持 gzip 或 DEFLATE 压缩):

    Accept-Encoding: gzip, deflate

    这会告诉服务器: 可以对返回的响应体进行压缩. 如下代码覆写了请求的 Accept-Encoding 头:

    NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
    [req setValue:@"" forHTTPHeaderField:@"Accept-Encoding"];

    URL 加载系统 API 并未提供完全删除请求中标准头的方式. 最好的方式就是使用空值覆写默认值

    3. 查看响应头

    当 HTTP 请求完成且没有错误时, 可能不包含头, 也可能包含多个头. 好下代码片段展示了对于成功完成的 HTTP 请求, 如何将头信息存储到日志文件中并获取到响应的 MIME 类型:

    NSHTTPURLResponse *response:
    NSError *error;
    [NSURLConnection sendSynchronousRequest:req
                                           returningResponse:&response
                                                             error:&error];
    NSDictionary *headers = [response allHeaderFields];
    NSLog(@"Headers = %@", headers);
    NSString *contentType = [headers objectForKey:@"Content-Type"];

    如果请求 URL 使用 HTTP 或 HTTPS 协议, 那么这么做是就是没问题的. allHeaderFields 方法会返回由所有响应头构成的字典, 其中包括 Set-Cookie 头. 如果响应中省略了头, 那么返回值就是 nil. 如果响应中包含了相同类型的多个头, 那么只会返回一个值. 这个返回值是由所有响应值拼接而成的, 并使用逗号分隔

    4. 主要的请求头

    很多 REST 服务器实现会通过检查 Accept 头来确定对返回负载的数据编码. 比如, 值为 application/xml 的 Accept 头会告诉服务器返回 XML 文档, 而 application/json 则会返回 JSON 文档

    Authorization 头可以与认证证书一起来避免对来自服务器的响应进行认证检查. 如下代码片段展示了如何添加 BASIC 认证头:

    NSString *basicBody = [NSString stringWithFormat:@"%@:%@", username, password];
    NSData *authData = [basicBody dataUsingEncoding:NSASCIIStringEncoding];

    // Base64 encode authData into a string called b64Data
    // code omitted to perform the Base64 encoding

    NSString *authValue = [NSString stringWithFormat:@"Basic %@", b64Data];

    [theRequest setValue:authValue forHTTPHeaderField:@"Authorization"];

    上述代码创建了名为 basicBody 的认证数据体, 其中包含用户名与密码并使用冒号分隔. 接下来将 basicBody 转换为 NSData 对象, 其中包含字符串的 ASCII 值. 然后将其以 Base64 编码为名为 b64Data 的字符串. 然后, 将单词 Basic 放在该字符串的前面, 作为 Authentication 头的值.

    你可能已经知道, BASIC 认证的安全性不如 Base64 编码的密码, 这意味着只能在 HTTPS 连接上使用这种方式. 该例并未使用 Base64 编码, 不过网络上有很多库实现了 Base64 编码数据.

    另一个有必要修改的头是 User-Agent, 创建它的目的是为 HTTP 服务器识别出浏览器类型. 在很多企业网络中, user agent 值用于根据浏览器类型将访问转向特定的服务器. 有些 HTTP 服务器会根据 user agent 值修改响应内容. 在默认情况下, 来自应用的 user agent 会包含应用产品名与版本、网络框架与版本, 以及OS 名与版本.  VideoDownloader 应用的 User-Agent 值如下所示:
    VideoDownloader/1.0 CFNetwork/548.1.4 Darwin/11.0.0

    应用的 User-Agent 头值会根据设备 iOS 版本的不同而不同, 当运行在 iOS 模拟器中时也会不同. 如果网络基础设施会根据 user agent 进行路由, 那么它必须能处理这些差别才行. 处理这些差别有两种方式:
    - 覆写 User-Agent 头以在各种平台上都提供相同的值
    - 根据 User-Agent 头的子集进行路由, 比如只根据应用名. 头的剩余部分会根据应用的版本以及所运行的设备而发生变化

    代码并非只能对请求使用标准的头. 可以使用几乎任何头名来自定义头: 然而, 这些自定义头名不能包含冒号或空格. 头名区分大小写, 需要与 Web 服务开发者协调来确定准确的头名与值. 自定义的头有助于传输认证与控制数据, 应用基础设施可以通过它们来支持应用的业务逻辑. 比如, 通过自定义的头提供会话标识符, 这样应用服务器就可以在将请求负载发送给应用逻辑前将会话上下文与其关联起来

    将自定义的头添加到请求中的方式与标准头一样, 如下代码片段所求:
    NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
    [req setValue:@"myValue" forHTTPHeaderField:@"My-Custom-Header"];

    相关文章

      网友评论

          本文标题:3.4.3 头信息操作进阶

          本文链接:https://www.haomeiwen.com/subject/gvkikttx.html