谈谈移动开发中必须要知道的网络知识

本文Demo的完整工程代码, 客户端基于iOS实现, 参考这里的StudyHTTP, 服务器基于node.js实现, 参考这里的StudyHTTP

目录

URI, URL和URN

定义

URI(Uniform Resource Identifier, 统一资源标识符)用来唯一的标识一个资源

URL(Uniform Resource Locator, 统一资源定位器)可以用来标识一个资源, 而且还指明了如何locate这个资源

URN(Uniform Resource name, 统一资源命名)是通过名字来标识资源

关系和区别

  • URL和URN都是一种URL
mobile-development-http_01.jpg
  • URI是以一种抽象的, 高层次概念定义统一资源标识, 而URL和URN则是具体的资源标识的方式

  • URI可以是绝对的也可以是相对的, 而URL则必须提供足够的信息来定位

更多可以参考你知道URL、URI和URN三者之间的区别吗?, URI和URL的区别, URI 和 URL的区别

RESTful API

什么是RESTful API?

首先要搞清楚什么是REST

REST(Representational State Transfer, 表现层状态转化)是一种网络架构规范

知道什么是REST, 就知道了什么是RESTful API

实现了REST规范的Web API就叫RESTful API

RESTful API有哪些特点?

  • 总是使用HTTPS

或许这不属于REST架构, 但是却是最最重要和基础的一点, 详细可以参考本文的这一章HTTPS

  • 将API的版本号放入URL
https://api.example.com/v1/
  • 每个网址代表一种资源

所以网址中不能有动词, 只能有名词, 且使用复数

https://api.example.com/v1/zoos
https://api.example.com/v1/animals
https://api.example.com/v1/employees
  • HTTP动词对应资源的具体操作类型
GET(SELECT) 从服务器取出资源(一项或多项) 
POST(CREATE) 在服务器新建一个资源
PUT(UPDATE) 在服务器更新资源(客户端提供改变后的完整资源) 
PATCH(UPDATE) 在服务器更新资源(客户端提供改变的属性) 
DELETE(DELETE) 从服务器删除资源

例子如下

GET /zoos 列出所有动物园
POST /zoos 新建一个动物园
GET /zoos/ID 获取某个指定动物园的信息
PUT /zoos/ID 更新某个指定动物园的信息(提供该动物园的全部信息)
PATCH /zoos/ID 更新某个指定动物园的信息(提供该动物园的部分信息)
DELETE /zoos/ID 删除某个动物园

更多RESTful API, 请参考RESTful API 设计指南

HTTP Header

Accept-Encoding

  • gzip - 使用gzip(GNU zip)压缩

  • compress - 使用Unix compress压缩

  • deflate - 使用zlib压缩

  • identity - 不进行编码

服务器开启压缩可以提高传输的效率, 详细可以参考expressjs/compression

Content-Type

常见的Content-Type有

  • application/json

  • text/json

application/json和text/json都是指json格式, 前者是官方规范, 后者是为了兼容, 详细参考What is the exact difference between content-type: text/json and application/json?

  • text/xml

  • text/html

  • text/plain

  • multipart/form-data

multipart/form-data用于POST上传文件时, 同时还需要设置boundary字段

在iOS开发中最有名的网络库AFNetworking

  • request serializers支持的Content-Type分别是

(1) AFJSONRequestSerializer

[mutableRequest setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];

(2) AFPropertyListRequestSerializer

[mutableRequest setValue:@"application/x-plist" forHTTPHeaderField:@"Content-Type"];

(3) AFHTTPRequestSerializer

application/x-www-form-urlencoded

(4) AFStreamingMultipartFormData

[self.request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", self.boundary] forHTTPHeaderField:@"Content-Type"];
  • response serializers支持的Content-Type分别是

(1) AFJSONResponseSerializer

self.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", nil];

(2) AFXMLParserResponseSerializer

self.acceptableContentTypes = [[NSSet alloc] initWithObjects:@"application/xml", @"text/xml", nil];

(3) AFXMLDocumentResponseSerializer

self.acceptableContentTypes = [[NSSet alloc] initWithObjects:@"application/xml", @"text/xml", nil];

(4) AFPropertyListResponseSerializer

self.acceptableContentTypes = [[NSSet alloc] initWithObjects:@"application/x-plist", nil];

(5) AFImageResponseSerializer

self.acceptableContentTypes = [[NSSet alloc] initWithObjects:@"image/tiff", @"image/jpeg", @"image/gif", @"image/png", @"image/ico", @"image/x-icon", @"image/bmp", @"image/x-bmp", @"image/x-xbitmap", @"image/x-win-bitmap", nil];

例如

在使用AFHTTPSessionManager的类构造方法+ (instancetype)manager生成对象时, 由于response serializer默认是AFJSONResponseSerializer

self.responseSerializer = [AFJSONResponseSerializer serializer];

如果response的Content-Type不是json类型的话, 那么就会出现类似下面的错误

2016-09-21 14:22:37.246 StudyHTTP[7589:623717] error = Error Domain=com.alamofire.error.serialization.response Code=-1016 "Request failed: unacceptable content-type: text/html" UserInfo={com.alamofire.serialization.response.error.response=<NSHTTPURLResponse: 0x610000225ba0> { URL: http://localhost:3000/users/ } { status code: 200, headers {
    Connection = "keep-alive";
    "Content-Length" = 23;
    "Content-Type" = "text/html; charset=utf-8";
    Date = "Wed, 21 Sep 2016 06:22:35 GMT";
    Etag = "W/\"17-i6pE/Ux9hQaoN6ksprpWig\"";
    "Proxy-Connection" = "Keep-alive";
    "X-Powered-By" = Express;
} }, NSErrorFailingURLKey=http://localhost:3000/users/, com.alamofire.serialization.response.error.data=<72657370 6f6e6420 77697468 20612072 65736f75 726365>, NSLocalizedDescription=Request failed: unacceptable content-type: text/html}

Range

对于只需获取部分资源的范围请求, 包含首部字段Range即可告知服务器资源的指定范围

使用这个字段就可以实现文件的断点续传

User-Agent

将创建请求的浏览器和用户代理名称等信息传达给服务器

例如

当使用Safari浏览打开百度时

User-Agent Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Safari/602.1.50

关于更多Content-Type, 可以参考常用对照表 HTTP Content-type

HTTP Status Code

2XX 成功状态码 请求正常处理完毕

200 OK

201 Created

202 Accepted

204 No Content

206 Partial Content

3XX 重定向状态码 需要进行附加操作以完成请求

301 Moved Permanently(永久重定向)

302 Found(临时重定向)

4XX 客户端错误状态码 服务器无法处理请求

400 Bad Request

401 Unauthorized

403 Forbidden

404 Not Found

5XX 服务器错误状态码 服务器处理请求出错

500 Internal Server Error

502 Bad Gateway

503 Service Unavailable

更多参考10 Status Code Definitions

HTTP数据传递

GET方式的参数会添加到URL中

例如URL请求和参数设置如下(实现基于iOSAFNetworking)

[self.sessionManager GET:@"http://localhost:3000/users/" parameters:@{@"key": @"value"} progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    NSLog(@"responseObject = %@", responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@"error = %@", error);
}];

那么HTTP请求实际的URL是

http://localhost:3000/users/?key=value

这时, 服务器通过request的query取出数据

console.log(req.query); // { key: 'value' }

POST方式的参数会添加到body中

例如URL请求和参数设置如下(实现基于iOSAFNetworking)

[self.sessionManager POST:@"http://localhost:3000/users/" parameters:@{@"key": @"value"} progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    NSLog(@"responseObject = %@", responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@"error = %@", error);
}];

此时HTTP请求的body就是

key=value

这时, 服务器通过request的body取出数据

console.log(req.body); // { key: 'value' }

HTTPS

发展至今, HTTPS已经可以算是标配了, 当然中国的网络环境总是"慢人一步", 为什么要如此重视HTTPS呢?

这是因为HTTP存在以下问题

  • 通信使用明文(不加密), 内容可能会被窃听

  • 不验证通信方的身份, 因此有可能遭遇伪装

  • 无法证明报文的完整性, 所以有可能已遭篡改

而HTTP加上加密处理和认证以及完整性保护后即是HTTPS

简单来说HTTPS(HTTP secure) = HTTP + 加密 + 认证 + 完整性保护

至于HTTPS为什么安全的具体分析, 可以参考SSL/TLS协议运行机制的概述

这里总结下HTTPS与HTTP的几个明显差异

  • HTTPS = HTTP over SSL/TLS (其中: SSL是Secure Sockets Layer的缩写, TLS是Transport Layer Security的缩写)

  • HTTPS需要到CA(Certificate Authority)申请证书

  • HTTP默认采用80端口, 而HTTPS默认采用443端口

HTTPS的简单流程是这样子的

  • 客户端向服务器端索要并验证公钥

  • 双方协商生成"对话密钥"

  • 双方采用"对话密钥"进行加密通信

详细的过程可以参考图解SSL/TLS协议

参考

更多文章, 请支持我的个人博客

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

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,580评论 18 139
  • 一说到REST,我想大家的第一反应就是“啊,就是那种前后台通信方式。”但是在要求详细讲述它所提出的各个约束,以及如...
    时待吾阅读 3,406评论 0 19
  • iOS网络编程读书笔记 Facade Tester客户端门面模式的实例(被动版本化) 被动版本化,所以硬编码URL...
    melouverrr阅读 1,598评论 3 7
  • API定义规范 本规范设计基于如下使用场景: 请求频率不是非常高:如果产品的使用周期内请求频率非常高,建议使用双通...
    有涯逐无涯阅读 2,517评论 0 6
  • (原话)谈谈对HTTP协议的理解:超文本传输协议,应用于OSI网络模型中的应用层,是用于服务器传输超文本到本地浏览...
    24_yu阅读 874评论 0 1