客戶端使用服務端API接口時惠险,需構(gòu)造HTTP請求頭呜达,一般情況下是初始化一個NSMutableURLRequest,然后設(shè)置請求方法滑潘、請求體垢乙,請求頭,如下:
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.0];
[request setHTTPMethod:@"POST"];
[request setHTTPBody:bodyData];
[request setValue:@"gzip, deflate" forHTTPHeaderField:@"Accept-Encoding"];
[request setValue:@"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[request setValue:[NSString stringWithFormat:@"%lu", (unsigned long)bodyData.length] forHTTPHeaderField:@"Content-Length"];
[request setValue:authorization forHTTPHeaderField:@"Authorization"];
猿題庫的網(wǎng)絡(luò)請求(YTKNetwork)已把請求方法语卤、請求體追逮,請求頭等封裝好允許用戶重載進行自定義。包括:
#pragma mark - Subclass Override
///=============================================================================
/// @name Subclass Override
///=============================================================================
/// Called on background thread after request succeded but before switching to main thread. Note if
/// cache is loaded, this method WILL be called on the main thread, just like `requestCompleteFilter`.
- (void)requestCompletePreprocessor;
/// Called on the main thread after request succeeded.
- (void)requestCompleteFilter;
/// Called on background thread after request succeded but before switching to main thread. See also
/// `requestCompletePreprocessor`.
- (void)requestFailedPreprocessor;
/// Called on the main thread when request failed.
- (void)requestFailedFilter;
/// The baseURL of request. This should only contain the host part of URL, e.g., http://www.example.com.
/// See also `requestUrl`
- (NSString *)baseUrl;
/// The URL path of request. This should only contain the path part of URL, e.g., /v1/user. See alse `baseUrl`.
///
/// @discussion This will be concated with `baseUrl` using [NSURL URLWithString:relativeToURL].
/// Because of this, it is recommended that the usage should stick to rules stated above.
/// Otherwise the result URL may not be correctly formed. See also `URLString:relativeToURL`
/// for more information.
///
/// Additionaly, if `requestUrl` itself is a valid URL, it will be used as the result URL and
/// `baseUrl` will be ignored.
- (NSString *)requestUrl;
/// Optional CDN URL for request.
- (NSString *)cdnUrl;
/// Requset timeout interval. Default is 60s.
///
/// @discussion When using `resumableDownloadPath`(NSURLSessionDownloadTask), the session seems to completely ignore
/// `timeoutInterval` property of `NSURLRequest`. One effective way to set timeout would be using
/// `timeoutIntervalForResource` of `NSURLSessionConfiguration`.
- (NSTimeInterval)requestTimeoutInterval;
/// Additional request argument.
- (nullable id)requestArgument;
/// Override this method to filter requests with certain arguments when caching.
- (id)cacheFileNameFilterForRequestArgument:(id)argument;
/// HTTP request method.
- (YTKRequestMethod)requestMethod;
/// Request serializer type.
- (YTKRequestSerializerType)requestSerializerType;
/// Response serializer type. See also `responseObject`.
- (YTKResponseSerializerType)responseSerializerType;
/// Username and password used for HTTP authorization. Should be formed as @[@"Username", @"Password"].
- (nullable NSArray<NSString *> *)requestAuthorizationHeaderFieldArray;
/// Additional HTTP request header field.
- (nullable NSDictionary<NSString *, NSString *> *)requestHeaderFieldValueDictionary;
/// Use this to build custom request. If this method return non-nil value, `requestUrl`, `requestTimeoutInterval`,
/// `requestArgument`, `allowsCellularAccess`, `requestMethod` and `requestSerializerType` will all be ignored.
- (nullable NSURLRequest *)buildCustomUrlRequest;
/// Should use CDN when sending request.
- (BOOL)useCDN;
/// Whether the request is allowed to use the cellular radio (if present). Default is YES.
- (BOOL)allowsCellularAccess;
/// The validator will be used to test if `responseJSONObject` is correctly formed.
- (nullable id)jsonValidator;
/// This validator will be used to test if `responseStatusCode` is valid.
- (BOOL)statusCodeValidator;
請求頭通過重寫方法- (NSDictionary *)requestHeaderFieldValueDictionary粹舵;
返回一個字典钮孵,然后在方法
- (AFHTTPRequestSerializer *)requestSerializerForRequest:(YTKBaseRequest *)request;
中將網(wǎng)絡(luò)請求序列化齐婴,供構(gòu)造NSURLSessionTask使用油猫。
- (NSDictionary *)requestHeaderFieldValueDictionary {
NSString *paraUrlString = AFQueryStringFromParameters([self requestArgument]);
NSString *authorization =[[YTKNetworkConfig sharedConfig] getAuthorization:[self requestUrl]];
return @{@"Accept-Encoding":@"gzip, deflate",
@"Content-Type":@"application/x-www-form-urlencoded; charset=utf-8",
@"Content-Length":[NSString stringWithFormat:@"%lu", (unsigned long)paraUrlString.length],
@"Authorization":authorization};
}
下面具體說說請求頭里幾個字段的含義:
Accept-Encoding
- 表示本地可以接收壓縮格式的數(shù)據(jù),而服務器在處理時就將大文件壓縮再發(fā)回客戶端⊙荩客戶端接收完成后在本地對數(shù)據(jù)進行解壓操作王浴。
- gzip:用于UNⅨ系統(tǒng)的文件壓縮敬特,HTTP協(xié)議上的gzip編碼是一種用來改進WEB應用程序性能的技術(shù)厘肮。大流量的WEB站點常常使用gzip讓用戶感受更快的速度转砖。這一般是指WWW服務器中安裝的一個功能恢筝,當有人來訪問這個服務器中的網(wǎng)站時蔫仙,服務器中的這個功能就將網(wǎng)頁內(nèi)容壓縮后傳輸?shù)絹碓L的電腦瀏覽器中顯示出來料睛。一般對純文本內(nèi)容可壓縮到原大小的40%,從而使得數(shù)據(jù)傳輸速度加快摇邦。當然這也會增加服務器的負載恤煞,一般服務器中都安裝有這個功能模塊的。
- deflate:一種使用LZ77算法與哈夫曼編碼(Huffman Coding)的一個無損數(shù)據(jù)壓縮無專利算法的壓縮技術(shù)施籍。
- HTTP內(nèi)容編碼和HTTP壓縮的區(qū)別:在HTTP協(xié)議中居扒,可以對內(nèi)容(也就是body部分)進行編碼, 可以采用gzip這樣的編碼丑慎。 從而達到壓縮的目的喜喂。 也可以使用其他的編碼把內(nèi)容攪亂或加密,以此來防止未授權(quán)的第三方看到文檔的內(nèi)容竿裂。所以我們說HTTP壓縮玉吁,其實就是HTTP內(nèi)容編碼的一種。
- HTTP壓縮的過程:
1腻异、客戶端發(fā)送Http request 給Web服務器, request 中有Accept-Encoding: gzip, deflate进副。 (告訴服務器, 瀏覽器支持gzip壓縮)悔常。
2敢会、服務器接到request后, 生成原始的Response, 其中有原始的Content-Type和Content-Length这嚣。
3鸥昏、服務器通過gzip,來對Response進行編碼姐帚, 編碼后header中有Content-Type和Content-Length(壓縮后的大小)吏垮, 并且增加了Content-Encoding:gzip. 然后把Response發(fā)送給客戶端。
4罐旗、客戶端接到Response后膳汪,根據(jù)Content-Encoding:gzip來對Response 進行解碼。 獲取到原始response后九秀, 然后處理數(shù)據(jù)的顯示遗嗽。 - 其它:compress表明實體采用Unix的文件壓縮程序;identity表明沒有對實體進行編碼鼓蜒。當沒有Content-Encoding header時痹换, 就默認為這種情況征字。gzip, compress, 以及deflate編碼都是無損壓縮算法,用于減少傳輸報文的大小娇豫,不會導致信息損失匙姜。 其中g(shù)zip通常效率最高, 使用最為廣泛冯痢。
Content-Type
- 表示內(nèi)容類型氮昧,一般是指客戶端存在的Content-Type,用于定義網(wǎng)絡(luò)文件的類型和網(wǎng)頁的編碼浦楣,決定客戶端將以什么形式袖肥、什么編碼讀取這個文件。即用于標識發(fā)送或接收到的數(shù)據(jù)的類型振劳,客戶端根據(jù)該參數(shù)來決定數(shù)據(jù)的打開方式昭伸。
- application/x-www-form-urlencoded:數(shù)據(jù)被編碼為名稱/值對,這是標準的編碼格式澎迎;multipart/form-data: 窗體數(shù)據(jù)被編碼為一條消息庐杨,頁上的每個控件對應消息中的一個部分。 text/plain: 窗體數(shù)據(jù)以純文本形式進行編碼夹供,其中不含任何控件或格式字符灵份。
1、當action為get時候哮洽,瀏覽器用x-www-form-urlencoded的編碼方式把form數(shù)據(jù)轉(zhuǎn)換成一個字串(name1=value1&name2=value2…)填渠,然后把這個字串a(chǎn)ppend到url后面,用?分割鸟辅,加載這個新的url氛什。
2、當action為post時候匪凉,瀏覽器把form數(shù)據(jù)封裝到http body中枪眉,然后發(fā)送到server。 如果沒有type=file的控件再层,用默認的application/x-www-form-urlencoded就可以了贸铜。 但是如果有type=file的話,就要用到multipart/form-data了聂受。瀏覽器會把整個表單以控件為單位分割蒿秦,并為每個部分加上Content-Disposition(form-data或者file),Content-Type(默認為text/plain),name(控件name)等信息,并加上分割符(boundary)蛋济。
Content-Length
- 表示述HTTP消息實體的傳輸長度棍鳖。消息實體長度:即Entity-length,壓縮之前的message-body的長度碗旅;
消息實體的傳輸長度:Content-length渡处,壓縮后的message-body的長度镜悉。(參數(shù)拼接成的字典)
Authorization
- HTTP基本認證是一種用來允許Web瀏覽器,或其他客戶端程序在請求時提供以用戶名和口令形式的憑證的登錄方式骂蓖。授權(quán)機制根據(jù)服務端定的規(guī)則確定。
- 認證 (authentication) 和授權(quán) (authorization) 的區(qū)別:你要登機川尖,你需要出示你的身份證和機票登下,身份證是為了證明你張三確實是你張三,這就是 authentication叮喳;而機票是為了證明你張三確實買了票可以上飛機被芳,這就是 authorization。 你要登陸論壇馍悟,輸入用戶名張三畔濒,密碼1234,密碼正確锣咒,證明你張三確實是張三侵状,這就是 authentication;再一check用戶張三是個版主毅整,所以有權(quán)限加精刪別人帖趣兄,這就是 authorization。
POST與GET區(qū)別
- 站在HTML角度:
1悼嫉、GET在瀏覽器回退時是無害的艇潭,而POST會再次提交請求。
2戏蔑、GET產(chǎn)生的URL地址可以被Bookmark蹋凝,而POST不可以。
3总棵、GET請求會被瀏覽器主動cache鳍寂,而POST不會,除非手動設(shè)置情龄。
4伐割、GET請求只能進行url編碼,而POST支持多種編碼方式刃唤。
5隔心、GET請求參數(shù)會被完整保留在瀏覽器歷史記錄里,而POST中的參數(shù)不會被保留尚胞。
6硬霍、GET請求在URL中傳送的參數(shù)是有長度限制的,而POST么有笼裳。
7唯卖、對參數(shù)的數(shù)據(jù)類型粱玲,GET只接受ASCII字符,而POST沒有限制拜轨。
8抽减、GET比POST更不安全,因為參數(shù)直接暴露在URL上橄碾,所以不能用來傳遞敏感信息卵沉。
9、GET參數(shù)通過URL傳遞法牲,POST放在Request body中史汗。 - 站在HTTP的角度:
1、HTTP是基于TCP/IP的關(guān)于數(shù)據(jù)如何在萬維網(wǎng)中如何通信的協(xié)議拒垃。HTTP的底層是TCP/IP停撞。所以GET和POST的底層也是TCP/IP,也就是說悼瓮,GET/POST都是TCP鏈接戈毒。GET和POST能做的事情是一樣一樣的。你要給GET加上request body横堡,給POST帶上url參數(shù)副硅,技術(shù)上是完全行的通的。HTTP只是個行為準則翅萤,而TCP才是GET和POST怎么實現(xiàn)的基本恐疲。
2、HTTP沒有要求套么,如果Method是POST數(shù)據(jù)就要放在BODY中培己。也沒有要求,如果Method是GET胚泌,數(shù)據(jù)(參數(shù))就一定要放在URL中而不能放在BODY中省咨。也就是說,GET和POST與數(shù)據(jù)如何傳遞沒有關(guān)系玷室。HTTP協(xié)議對GET和POST都沒有對長度的限制零蓉。安全不安全和GET、POST沒有關(guān)系穷缤。
3敌蜂、GET產(chǎn)生一個TCP數(shù)據(jù)包;POST產(chǎn)生兩個TCP數(shù)據(jù)包津肛。對于GET方式的請求章喉,瀏覽器會把http header和data一并發(fā)送出去,服務器響應200(返回數(shù)據(jù));而對于POST秸脱,瀏覽器先發(fā)送header落包,服務器響應100 continue,瀏覽器再發(fā)送data摊唇,服務器響應200 ok(返回數(shù)據(jù))咐蝇。
HTTP狀態(tài)碼大全
1、1** 信息巷查,服務器收到請求有序,需要請求者繼續(xù)執(zhí)行操作
2、2** 成功吮便,操作被成功接收并處理
3笔呀、3** 重定向幢踏,需要進一步的操作以完成請求
4髓需、4** 客戶端錯誤,請求包含語法錯誤或無法完成請求
5房蝉、5** 服務器錯誤僚匆,服務器在處理請求的過程中發(fā)生了錯誤