3.4.3 头信息操作进阶

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"];

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,045评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,114评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,120评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,902评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,828评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,132评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,590评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,258评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,408评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,335评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,385评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,068评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,660评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,747评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,967评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,406评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,970评论 2 341

推荐阅读更多精彩内容