一、IP 地址(主機名):php
網絡中設備的惟一標示。不易記憶,能夠用主機名(域名)。html
1) IP V4:前端
2) 本地迴環地址:ios
每臺機器都有本身的本地迴環地址,ip 爲 127.0.0.1 ,主機名爲 localhost。若是 127.0.0.1 ping 不通,則網卡不正常。git
本地 hosts 文件修改,終端:程序員
$ cd /etc
$ sudo vim hosts
$ 輸入密碼進入 hosts 文件編輯界面
$ 將光標移動到指定位置
- 英文輸入模式下按 i 鍵進入編輯狀態,
- 英文輸入模式下按 esc 鍵進入命令狀態,
- 在命令狀態下輸入 :wq 回車,保存退出 hosts 文件。
二、端口號:github
有效端口爲 0 ~ 65535,其中 0 ~ 1024 由系統使用或者保留端口,開發中不要使用 1024 如下的端口。web
1) Netcat 的使用:算法
$ nc -lk 12345
,開啓監聽,終端將始終監聽本地計算機 12345 端口的數據。三、傳輸協議(通信的規則):數據庫
1) TCP:傳輸控制協議:
2) UDP:用戶數據報協議:
3) 常見網絡協議:
應用層協議 | 端口 | 說明
-----------------|----------------|---------------------------------
HTTP | 80 | 超文本傳輸協議
HTTPS | 443 | HTTP+SSL,HTTP 的安全版
FTP | 20, 21, 990 | 文件傳輸
POP3 | 110 | 郵局協議
SMTP | 25 | 簡單郵件傳輸協議
telnet | 23 | 遠程終端協議
ISO 參考模型 | TCP/IP 參考 | 說明 |
---|---|---|
應用層 | 應用層 | FTP,HTTP,TELNET,SMTP,DNS 等協議 |
表示層 | ||
會話層 | ||
傳輸層 | 傳輸層 | Socket 開發,TCP 協議,UDP 協議 |
網絡層 | 網絡互連層 | 路由器,IP 協議,ICMP 協議,ARP 協議,RARP 協議和 BOOTP 協議 |
數據鏈路層 | 網絡接口層 | 交換機 |
物理層 | 網線 |
HTTP 通訊機制是在一次完整的 HTTP 通訊過程當中,Web 瀏覽器與 Web 服務器之間將完成下列 7 個步驟:
一、創建 TCP 鏈接
二、Web 瀏覽器向 Web 服務器發送請求命令
三、Web 瀏覽器發送請求頭信息
四、Web 服務器應答
五、Web 服務器發送應答頭信息
六、Web 服務器向瀏覽器發送數據
七、Web 服務器關閉 TCP 鏈接
當瀏覽器向 Web 服務器發出請求時,它向服務器傳遞了一個數據塊,也就是請求信息,HTTP 請求信息由 3 部分組成:
請求體
如:
GET /videos.jsp HTTP/1.1 // 請求行 Host: localhost // 請求頭 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:36.0) Gecko/20100101 Firefox/36.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,* / *;q=0.8 Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7 Connection: keep-alive username=jinqiao&password=1234 // 請求體
一、請求行:
請求的第一行,其組成爲:請求方法 請求路徑 協議/版本
請求行 :GET /videos.jsp HTTP/1.1
協議/版本:HTTP/1.1
(1) 請求方法:
根據 HTTP 標準,HTTP 請求可使用多種請求方法。例如:HTTP1.1 支持 7 種請求方法:GET、POST、HEAD、OPTIONS、PUT、DELETE 和 TARCE。在 Internet 應用中,最經常使用的方法是 GET 和 POST。
GET 方法:
GET 方法是默認的 HTTP 請求方法,經過請求 URL 獲得資源。咱們平常用 GET 方法來提交表單數據,然而用 GET 方法提交的表單數據只通過了簡單的編碼,同時它將做爲 URL 的一部分向 Web 服務器發送,所以,若是使用 GET 方法來提交表單數據就存在着安全隱患上。例如:
Http://127.0.0.1/login.jsp?Name=zhangshi&Age=30&Submit=%cc%E+%BD%BB
從上面的 URL 請求中,很容易就能夠辯認出表單提交的內容。(?以後的內容)另外因爲 GET 方法提交的數據是做爲 URL 請求的一部分因此提交的數據量不能太大。
POST 方法:
POST 方法是 GET 方法的一個替代方法,用於添加新的內容。它主要是向 Web 服務器提交表單數據,尤爲是大批量的數據。POST 方法克服了 GET 方法的一些缺點。經過 POST 方法提交表單數據時,數據不是做爲 URL 請求的一部分而是做爲標準數據傳送給 Web 服務器,這就克服了 GET 方法中的信息沒法保密和數據量過小的缺點。所以,出於安全的考慮以及對用戶隱私的尊重,一般表單提交時採用 POST 方法。
從編程的角度來說,若是用戶經過 GET 方法提交數據,則數據存放在 QUERY_STRING 環境變量中,而 POST 方法提交的數據則能夠從標準輸入流中獲取。
HEAD:相似於 GET, 只返回響應,不返回實體數據,用於檢查對象是否存在,以及獲得對象的元數據,下載數據前使用
apache2 中,可以使用 Limit,LimitExcept 進行訪問控制的方法包括:GET, POST, PUT, DELETE, CONNECT,OPTIONS, PATCH, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE,LOCK, 和 UNLOCK。其中, HEAD GET POST OPTIONS PROPFIND 是和讀取相關的方法,MKCOL PUT DELETE LOCK UNLOCK COPY MOVE PROPPATCH 是和修改相關的方法。
(2) 請求路徑:
(3) 協議/版本:
二、請求頭:
請求頭包含許多有關客戶端環境和請求體的有用信息。例如,請求頭能夠聲明瀏覽器所用的語言,請求體的長度等。當咱們打開一個網頁時,瀏覽器要向網站服務器發送一個 HTTP 請求頭,而後網站服務器根據 HTTP 請求頭的內容生成當次請求的內容發送給瀏覽器。
Host: localhost // 請求主機 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:36.0) Gecko/20100101 Firefox/36.0 // 告訴服務器客戶端的類型 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 // 告訴服務器客戶端支持的格式 Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 // 告訴服務器客戶端的語言 Accept-Encoding: gzip, deflate // 告訴服務器客戶端支持的壓縮格式 Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7 // 告訴服務器客戶端字符編碼 Connection: keep-alive // 告訴服務器鏈接類型 Content-Length: 4817 // 提交給服務器的內容長度 Content-Type: text/html // 提交給服務器的內容類型 Authorization: authorString // 訪問服務器的驗證信息 Range: bytes=0-499 // 指定要返回的數據範圍
(1) Host
表示請求的服務器網址。請求報頭域主要用於指定被請求資源的 Internet 主機和端口號,它一般從 HTTP URL 中提取出來的。
例如: 咱們在瀏覽器中輸入:http://www.guet.edu.cn/index.html
,瀏覽器發送的請求消息中,就會包含 Host 請求報頭域,以下:Host:http://www.guet.edu.cn
,此處使用缺省端口號 80,若指定了端口號,則變成:Host:指定端口號
。
(2) User-Agent
告訴 HTTP 服務器,客戶端使用的操做系統和瀏覽器的名稱和版本。
User-Agent(用戶代理),簡稱 UA,它是一個特殊字符串頭,使得服務器可以識別客戶端使用的操做系統及版本、CPU 類型、瀏覽器及版本、瀏覽器渲染引擎、瀏覽器語言、瀏覽器插件等。
例如:User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; CIBA; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; InfoPath.2; .NET4.0E)
(3) Accept
告訴服務器瀏覽器端能夠接受的媒體類型。
客戶端支持的 MIME 類型分別是 text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8,優先順序是它們從左到右的排列順序。
text/html,application/xhtml+xml,application/xml 都是 MIME 類型,也能夠稱爲媒體類型和內容類型,斜槓前面的是 type(類型),斜槓後面的是 subtype(子類型);type 指定大的範圍,subtype 是 type 中範圍更明確的類型,即大類中的小類。
text/html :表示 html 文檔;
application/xml :表示 xml 文檔。
(4) Accept-Language
告訴服務器瀏覽器申明本身接收的語言。
語言跟字符集的區別:中文是語言,中文有多種字符集,好比 big5,gb2312,gbk 等等;
例如:Accept-Language: en-us
zh :表示中文
(5) Accept-Encoding
瀏覽器申明本身接收的編碼方法,一般指定壓縮方法,是否支持壓縮,支持什麼壓縮方法(gzip,deflate),(注意:這不是隻字符編碼);
例如:Accept-Encoding: gzip, deflate
deflate :是同時使用了 LZ77 算法與哈夫曼編碼(Huffman Coding)的一個無損數據壓縮算法
(6) Accept-Charset
瀏覽器申明本身接收的字符集,這就是本文前面介紹的各類字符集和字符編碼,如 gb2312,utf-8(一般咱們說Charset包括了相應的字符編碼方案);
* :表示任意字符編碼,雖然 q 都是等於 0.7,但明確指定的 GB2312,utf-8 比 * 具備更高的優先級
(7) Connection
告訴服務器鏈接類型。
Connection:Keep-Alive :表示持久鏈接,長鏈接。當一個網頁打開完成後,客戶端和服務器之間用於傳輸 HTTP 數據的 TCP 鏈接不會關閉,若是客戶端再次訪問這個服務器上的網頁,會繼續使用這一條已經創建的鏈接。
Connection:close :表明一個 Request 完成後,客戶端和服務器之間用於傳輸 HTTP 數據的 TCP 鏈接會關閉,當客戶端再次發送 Request,須要從新創建 TCP 鏈接。
長鏈接:連上服務器就不斷開。雙方傳遞數據,不須要再次創建鏈接。
短鏈接:連上服務器,獲取完數據,就當即斷開。HTTP 訪問,都是短鏈接,使用狀況很是多。
(8) Content-Length
發送給HTTP服務器數據的長度。
例如: Content-Length:38
(9) Content-Type
提交給服務器的內容類型
例如:Content-Type: application/x-www-form-urlencoded
(10) Authorization
(11) Range
指定要返回的數據範圍
- :用於分隔,前面的數字表示起始字節數,後面的數組表示截止字節數,沒有表示到末尾。
, :用於分組,能夠一次指定多個 Range,不過不多用。
(12) Referer
提供了 Request 的上下文信息的服務器,告訴服務器我是從哪一個連接過來的,好比從我主頁上連接到一個朋友那裏,他的服務器就可以從 HTTP Referer中統計出天天有多少用戶點擊我主頁上的連接訪問他的網站。
例如: Referer:http://translate.google.cn/?hl=zh-cn&tab=wT
(13) Pragma
防止頁面被緩存,在 HTTP/1.1 版本中,它和 Cache-Control:no-cache 做用如出一轍,Pargma 只有一個用法,
例如:Pragma:no-cache
(14) Cookie
三、請求體:
請求頭和請求體之間是一個空行,這個行很是重要,它表示請求頭已經結束,接下來的是請求體。請求體中能夠包含客戶提交的查詢字符串信息。如:
username=jinqiao&password=1234
在以上的例子的 HTTP 請求中,請求的正文只有一行內容。固然,在實際應用中,HTTP 請求體能夠包含更多的內容。
HTTP 應答與 HTTP 請求類似,HTTP 響應也由 3 個部分構成,分別是:
響應正文
如:
HTTP/1.1 200 OK // 狀態行 Date: Wed, 29 Jun 2016 10:31:34 GMT // 響應頭 Server: Apache/2.4.18 (Unix) Content-Location: index.html.en Content-Length: 4817 Content-Type: text/html Keep-Alive: timeout=5, max=100 <html> // 響應正文 <body> <h1>It works!</h1> </body> </html>
一、狀態行:
HTTP 響應的第一行相似於 HTTP 請求的第一行,其組成爲:協議/版本 狀態碼 狀態碼描述
狀態行 :HTTP/1.1 200 OK
狀態碼 :200 OK
(1) 協議/版本:
(2) 狀態碼:
HTTP 應答碼也稱爲狀態碼,它反映了 Web 服務器處理 HTTP 請求狀態。HTTP 應答碼由 3 位數字構成,其中首位數字定義了應答碼的類型:
(3) 狀態碼描述:
用來解析狀態碼的狀態。
二、響應頭:
響應頭也和請求頭同樣包含許多有用的信息,例如服務器類型、日期時間、內容類型和長度等:
Date: Wed, 29 Jun 2016 10:31:34 GMT // 訪問日期 Server: Apache/2.4.18 (Unix) // 訪問服務器的類型 Content-Location: index.html.en // 訪問的文件名 Content-Length: 4817 // 訪問文件的大小 Content-Type: text/html // 訪問文件的類型 Keep-Alive: timeout=5, max=100 // 鏈接類型
(1) Cache-Control
這個是很是重要的規則。這個用來指定 Response-Request 遵循的緩存機制。各個指令含義以下
Cache-Control:Public
能夠被任何緩存所緩存Cache-Control:Private
內容只緩存到私有緩存中Cache-Control:no-cache
全部內容都不會被緩存(2) Content-Type
WEB 服務器告訴瀏覽器本身響應的對象的類型和字符集。
Content-Type:text/html; charset=utf-8
Content-Type:text/html;charset=GB2312
Content-Type:image/jpeg
(3) Expires
Expires:Tue, 08 Feb 2022 11:35:14 GMT
(4) Last-Modified
Last-Modified: Wed, 21 Dec 2011 09:09:10 GMT
(5) Server
Server:Microsoft-IIS/7.5
(6) X-AspNet-Version
X-AspNet-Version: 4.0.30319
(7) X-Powered-By
X-Powered-By: ASP.NET
(8) Connection
Connection:keep-alive
當一個網頁打開完成後,客戶端和服務器之間用於傳輸 HTTP 數據的 TCP 鏈接不會關閉,若是客戶端再次訪問這個服務器上的網頁,會繼續使用這一條已經創建的鏈接。Connection:close
表明一個 Request 完成後,客戶端和服務器之間用於傳輸 HTTP 數據的 TCP 鏈接會關閉,當客戶端再次發送 Request,須要從新創建 TCP 鏈接。(9) Content-Length
Content-Length: 19847
(10) Date
Date: Sat, 11 Feb 2012 11:35:14 GMT
三、響應正文:
響應正文就是服務器返回的 HTML 頁面,響應頭和正文之間也必須用空行分隔。
<html> <body> <h1>It works!</h1> </body> </html>
Web 應用最多見的用途之一是電子商務,能夠利用 Web 服務器端程序令人們可以網絡購物,須要指出一點是,缺省狀況下,經過 Internet 發送信息是不安全的,若是某人碰巧截獲了你發給朋友的一則消息,他就能打開它,假想在裏面有你的信用卡號碼,這會有多麼糟糕,幸運的是,不少 Web 服務器以及 Web 瀏覽器都有創立安全鏈接的能力,這樣它們就能夠安全的通訊了。
經過 Internet 提供安全鏈接最多見的標準是安全套接層(Secure Sockets layer,SSl)協議。SSL 協議是一個應用層協議(和 HTTP 同樣),用於安全方式在 Web 上交換數據,SSL 使用公開密鑰編碼系統。從本質講,這意味着業務中每一方都擁有一個公開的和一個私有的密鑰。當一方使用另外一方公開密鑰進行編碼時,只有擁有匹配密鑰的人才能對其解碼。簡單來說,公開密鑰編碼提供了一種用於在兩方之間交換數據的安全方法,SSL 鏈接創建以後,客戶和服務器都交換公開密鑰,並在進行業務聯繫以前進行驗證,一旦雙方的密鑰都經過驗證,就能夠安全地交換數據。
基於 http 協議的 "文件" 服務器,實現文件的上傳/下載/修改/刪除。
WebDav 權限,受權信息的格式 BASIC (用戶名:口令)base64
安全性並不高,密碼很容易被攔截和破解。
應用場景:開發企業級的管理系統,能夠用 WebDav 搭建一個內部的文件管理服務器,只是在公司內網使用。
GET 查
PUT/DELETE 都須要設置權限驗證,新增(修改)/刪除 服務器的內容,須要權限驗證。
請求狀態碼:
status code: 204 修改
status code: 401 身份驗證失敗
status code: 404 文件不存在
status code: 401 身份驗證失敗
對於移動客戶端來講,網絡的重要性不言而喻。常見的網絡請求有同步 GET,同步 POST,異步 GET,異步 POST。
同步和異步網絡請求的區別:
一、同步網絡請求,主線程負責數據的、視圖的初始化和界面的展現等。同步網絡數據請求也在主線程中進行,若是耗時較長,在數據請求完畢以前,其餘線程一概不響應,會對主線程形成阻塞,形成程序假死現象,用 戶體驗極差。
二、異步網絡請求,主線程負責數據的、視圖的初始化和界面的展現等。異步網絡數據請求的時候,會在主線程以外單獨開闢一個線程去處理網絡請求,主線程依然處於可交互狀態,程序運行流暢。
許多開發者都會認爲同步的鏈接將會堵塞主線程,其實這種觀點是錯誤的。一個同步的鏈接是會阻塞調用它的線程。若是你在主線程中建立一個同步鏈接,沒錯,主線程會阻塞。可是若是你並非從主線程開啓的一個同步的鏈接,它將會相似異步的鏈接同樣。所以這種狀況並不會堵塞你的主線程。事實上,同步和異步的主要區別就是運行 runtime 爲會異步鏈接建立一個線程,而同步鏈接則不會。
使用 iOS 的網絡接口(NSURLSession/NSURLConnection)開發時,上傳和下載操做通常都是一條線程異步執行的。可是代理回調有多是多個線程。
GET 請求和 POST 請求的區別:
GET 請求:
POST 請求:
一、url:NSURL
要訪問的資源路徑。
+ (nullable instancetype)URLWithString:(NSString *)URLString; + (nullable instancetype)URLWithString:(NSString *)URLString relativeToURL:(nullable NSURL *)baseURL;
1) URL 結構:
// 帶方括號 [] 的爲可選項 scheme://host[:port]/path/[;parameters][?query]#fragment
property | url | description |
---|---|---|
URL | https://swiftinaction.com/example?section=5&ie=utf-8 | URL 路徑 |
scheme | https | 協議,http、https、ftp、file(本地文件)、data(數據) |
host | swiftinaction.com | 主機,能夠利用 Reachability 框架判斷可否鏈接到要訪問的主機 |
port | nil | 端口,nil 使用默認端口 80 |
path | example | 路徑,不包含協議頭/主機地址/端口/參數 |
parameters | nil | 參數,變量名和變量值成對出現,使用 = 分隔,多個參數使用 & 鏈接 |
query | section=5&ie=utf-8 | 查詢參數 |
fragment | nil | 信息片斷 |
absoluteString | https://swiftinaction.com/example?section=5&ie=utf-8 | 完整的字符串 |
resourceSpecifier | //swiftinaction.com/example?section=5&ie=utf-8 | 不包含協議頭的剩餘內容 |
baseURL | nil | 參照路徑,默認爲 nil |
2) URL 特殊字符處理:
在一個 URL 中,全部的字符都必須是 ASCII 碼,不能包含特殊符號,好比 空格、中文等,若是有特殊符號須要使用百分號轉義。
1> 百分號轉義編碼規則:
字符 | 做用 | 十六進制值 |
---|---|---|
/ | 分隔目錄和子目錄 | %2F |
? | 分隔 URL 和查詢參數 | %3F |
& | 分隔參數 | %26 |
# | 指定書籤 | %23 |
% | 指定特殊字符 | %25 |
" | %22 | |
\ | %5C | |
` | 轉義 ` | %60 |
| |
轉義 | |
%7C |
{ | 轉義 { | %7B |
} | 轉義 } | %7D |
[ | 轉義 [ | %5B |
] | 轉義 ] | %5D |
< | 轉義 < | %3C |
> | 轉義 > | %3E |
^ | 轉義 中文字符 | |
_ | 轉義 空格 | %20 |
2> 百分號轉義 編碼:
stringByAddingPercentEscapesUsingEncoding 只對 ` # % ^ { } [ ] | " < > 加 空格 共 14 個字符編碼,不包括 & ? 等符號,iOS9 中此方法被淘汰,建議用 stringByAddingPercentEncodingWithAllowedCharacters 方法,此方法中 Characters 的建立方式以下:
編碼方式:
// 轉義的字符包含 」#%/<>?@\^`{|} NSCharacterSet *allowedCharacters = [NSCharacterSet URLHostAllowedCharacterSet]; // 轉義的字符包含 "#%;<>?[\]^`{|} NSCharacterSet *allowedCharacters = [NSCharacterSet URLPathAllowedCharacterSet]; // 轉義的字符包含 "#%<>[\]^`{|} NSCharacterSet *allowedCharacters = [NSCharacterSet URLQueryAllowedCharacterSet]; // 轉義的字符包含 "#%<>[\]^`{|} NSCharacterSet *allowedCharacters = [NSCharacterSet URLFragmentAllowedCharacterSet]; // 轉義的字符包含 "#%/:<>?@[\]^`{|} NSCharacterSet *allowedCharacters = [NSCharacterSet URLPasswordAllowedCharacterSet]; // 轉義的字符包含 "#%/:<>?@[\]^` NSCharacterSet *allowedCharacters = [NSCharacterSet URLUserAllowedCharacterSet]; // 自定義方式 NSCharacterSet *customAllowedSet = [NSCharacterSet characterSetWithCharactersInString:@"`#%^{}\"[]|\\<> "].invertedSet;
使用:
對整個 URL 進行轉義:
NSString *urlStr = @"http://192.168.88.200/測試/demo.json"; NSString *newUrlStr = [urlStr stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet characterSetWithCharactersInString:@"^"].invertedSet]; NSURL *url = [NSURL URLWithString:newUrlStr];
對部分 URL 進行轉義:
NSString *urlStr = [@"測試/demo.json" stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet characterSetWithCharactersInString:@"^"].invertedSet]; NSString *newUrlStr = [@"http://192.168.88.200" stringByAppendingPathComponent:urlStr]; NSURL *url = [NSURL URLWithString:newUrlStr];
3> 百分號轉義 解碼:
二、request:NSURLRequest
要發送給服務器的請求。
+ (instancetype)requestWithURL:(NSURL *)URL; + (instancetype)requestWithURL:(NSURL *)URL cachePolicy:(NSURLRequestCachePolicy)cachePolicy timeoutInterval:(NSTimeInterval)timeoutInterval;
1) 參數:
1> URL:要訪問的資源路徑
2> cachePolicy:緩存策略
// 默認的緩存策略,會在本地緩存 NSURLRequestUseProtocolCachePolicy = 0, // 忽略本地緩存數據,永遠都是從服務器獲取數據,不使用緩存 NSURLRequestReloadIgnoringLocalCacheData = 1, // 應用場景:股票,彩票 NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData // 首先使用緩存,若是沒有本地緩存,才從原地址下載 NSURLRequestReturnCacheDataElseLoad = 2, // 使用本地緩存,從不下載,若是本地沒有緩存,則請求失敗和 "離線" 數據訪問有關,能夠和 Reachability 框架結合使用, // 若是用戶聯網,直接使用默認策略。若是沒有聯網,可使用返回緩存策略鄭重提示:要把用戶拉到網絡上來。 NSURLRequestReturnCacheDataDontLoad = 3, // 無視任何緩存策略,不管是本地的仍是遠程的,老是從原地址從新下載 NSURLRequestReloadIgnoringLocalAndRemoteCacheData = 4, // Unimplemented // 若是本地緩存是有效的則不下載,其餘任何狀況都從原地址從新下載 NSURLRequestReloadRevalidatingCacheData = 5, // Unimplemented 緩存的數據保存在沙盒路徑下 Caches 文件夾中的 SQLite 數據庫中。
3> timeoutInterval:訪問超時時長
建議時長:15~30s,不要設置的過短.
AFNetWorking: 60s
2) NSURLRequest (NSHTTPURLRequest):
1> HTTPMethod:請求方法
2> HTTPBody:請求體
3> HTTPShouldHandleCookies:是否須要處理 Cookies
4> allHTTPHeaderFields:全部 HTTP 請求頭字典
3) 請求行:
4) 請求頭:
5) 請求體:
三、response:NSURLResponse
從服務器返回的響應。
void (^)(NSURLResponse* __nullable response, NSData* __nullable data, NSError* __nullable connectionError)
1) 參數:
1> response:服務器返回的響應
2> data
3> onnectionError
2) NSURLResponse/NSHTTPURLResponse:
1> statusCode:服務器返回的狀態碼
1XX 消息,2XX 成功,3XX 擴展屬性,4XX 客戶端錯誤,5XX 服務器錯誤
200 成功
2> URL:服務器返回的 URL
3> MIMEType:數據類型
4> expectedContentLength:預期的數據長度
5> suggestedFilename:建議的文件名
6> textEncodingName:文本的編碼名稱
若是沒有特殊指定,統一使用 UTF8。
字符編碼:
3) 狀態行:
4) 響應頭:
5) 響應體:
四、請求結果處理:
1) 服務器返回給客戶端的數據樣式:
2) 序列化/反序列化:
3) 錯誤處理標準代碼:
// 有的時候,沒有錯誤,可是也獲取不到數據 if (error != nil || data == nil) { // 不要告訴用戶太準確的錯誤信息 NSLog(@"您的網絡不給力,請稍候再試 !"); return; } NSLog(@"網絡請求成功 %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
iOS9 引入了新特性 App Transport Security (ATS),新特性要求 App 內訪問的網絡必須使用 HTTPS 協議。iOS9 把全部的 http 請求都改成 https,系統發送的網絡請求將統一使用 TLS 1.2 SSL。採用 TLS 1.2 協議,目的是強制加強數據訪問安全,並且系統 Foundation 框架下的相關網絡請求,將再也不默認使用 Http 等不安全的網絡協議,而默認採用 TLS 1.2。服務器所以須要更新,以解析相關數據。如不更新,可經過在 Info.plist 中聲明,倒退回不安全的網絡請求。
一、關閉強制 https 請求:
設置以下,添加 App Transport Security Settings 項,在其下添加 Allows Arbitrary Loads 並設置值爲 YES。
設置代碼以下:
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict>
二、設置 http 請求例外:
設置以下,NSIncludeSubdomains 顧名思義是包括子域的意思。
設置代碼以下:
<key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <key>qq.com</key> <dict> <key>NSIncludesSubdomains</key> <true/> </dict> <key>sina.com.cn</key> <dict> <key>NSIncludesSubdomains</key> <true/> </dict> </dict> </dict>
一、URL 編碼表單數據
Content-Type: application/x-www-form-urlencoded
主要向服務器提交與用戶隱私相關的信息。好比用戶登陸。
1) 特色:
這種方式訪問服務器,只須要指定訪問方法和數據體便可。 Content-Type 和 Content-Length 會自動完成。Content-Type 是客戶端告訴服務器發送數據的類型。Content-Length 發送的數據長度。
2) 實現代碼:
request.HTTPMethod = @"POST"; request.HTTPBody = [bodyString dataUsingEncoding:NSUTF8StringEncoding]; 在 firebug 中,能夠經過 POST -> 源代碼,將發送的 httpbody 的內容粘貼出來。
二、二進制數據 編碼表單數據
Content-Type: multipart/form-data
向服務器上傳文件,可以上傳文件的大小受服務器限制,PHP 限制是 2M。
1) 實現代碼:
request.HTTPMethod = @"POST"; request.HTTPBody = 使用規定的格式拼接 // 設置請求頭格式,如:Content-Type: multipart/form-data; boundary=%@ Content-Type: multipart/form-data; boundary(分隔線)=(能夠隨便寫,ASCII,字母和數字) // 設置文件類型格式,8 進制流,若是不想告訴服務器具體的文件類型,可使用這個 Content-Type: application/octet-stream
2) 文件上傳參數設置:
Content-Type:客戶端告訴服務器上傳文件的文件類型。
文件類型:
image/jpeg | 圖片文件 |
---|---|
image/png | 圖片文件 |
image/gif | 圖片文件 |
audio/mpeg | mp3 文件 |
video/mp4 | mp4 文件 |
text/html | html 文本文件 |
text/plain | txt 文本文件 |
text/rtf | rtf 文本文件 |
application/pdf | pdf 文件 |
application/json | json 文件 |
application/octet-stream | 8 進制流,若是不想告訴服務器具體的文件類型,可使用這個 |
name (text) :後臺規定的文本內容字段名,是負責上傳文件的腳本中的字段名
3) 文件上傳數據封裝:
有些服務器能夠在上傳文件的同時,提交一些文本內容給服務器。典型應用:新浪微博,上傳圖片的同時,發送一個微博。
如下部分,是發送給服務器的二進制數據的組成格式,若是在 iOS 中,要實現 POST 上傳文件,須要按照如下格式拼接數據。格式是 W3C 指定的標準格式,蘋果沒有作任何封裝。
1> 上傳單個文件
#define boundary @"uploadBoundary" // 設置請求頭 Content-Type: multipart/form-data; boundary=boundary // 上傳的文件數據封裝 --- 二進制數據格式 --boundary\r\n Content-Disposition: form-data; name="userfile"; filename="文件1.txt"\r\n // 設置文件名 Content-Type: application/octet-stream\r\n // 設置文件類型 \r\n 待上傳文件的二進制數據 \r\n --boundary\r\n Content-Disposition: form-data; name="usertext"\r\n // 設置文本字段名 \r\n 待上傳文本內容二進制數據 \r\n --boundary-- \r\n
2> 上傳多個文件
#define boundary @"uploadBoundary" // 設置請求頭 Content-Type: multipart/form-data; boundary=boundary // 上傳的文件數據封裝 --- 二進制數據格式 --boundary\r\n Content-Disposition: form-data; name="userfile[]"; filename="文件1.txt"\r\n // 設置文件名,第一個上傳的文件 Content-Type: application/octet-stream\r\n // 設置文件類型 \r\n 待上傳文件的二進制數據 \r\n --boundary\r\n Content-Disposition: form-data; name="userfile[]"; filename="文件2.txt"\r\n // 設置文件名,第二個上傳的文件 Content-Type: application/octet-stream\r\n // 設置文件類型 \r\n 待上傳文件的二進制數據 \r\n --boundary\r\n Content-Disposition: form-data; name="usertext"\r\n // 設置文本字段名 \r\n 待上傳文本內容二進制數據 \r\n --boundary-- // 結束分割線標記 \r\n
4) 關於第三方框架:
5) 爲何要同時上傳多個文件:
三、RESTful 設計風格
主要用在後端開發的,前端程序員只要知道便可。
1) 最直觀的特色:
2) 主要的表現形式:
使用一個 URL,使用不一樣的 HTTP 訪問方法,表達不一樣的語義。
示例:http://www.xxx.com/product/123
DELETE http://www.xxx.com/product/123 語義:在服務器 "刪除" 產品代號是123 的產品記錄
POST 提交二進制數據,須要提交一個 JSON 格式的二進制數據,後端程序員,能夠直接反序列化,獲得 JSON 中的字典信息。
分別對應:增,刪,改,查
3) POST 數據編碼類型:
1> Content-Type: application/json
向服務器發送 JSON 數據。
[p dictionaryWithValuesForKeys:@[@"username", @"age", @"title", @"height"]]; 模型轉字典,傳入的數組是須要序列化的屬性 [NSJSONSerialization isValidJSONObject:obj]; 判斷給定的對象可以被序列化 [NSJSONSerialization dataWithJSONObject:obj options:0 error:NULL]; 序列化
2> Content-Type: text/xml
向服務器發送 XML 數據。
iOS 開發極少用,若是開發中碰到可使用 GData 框架。
一、HEAD 方法:
HEAD 方法一般是用來在下載文件以前,獲取遠程服務器上的文件信息。與 GET 方法相比,一樣可以拿到響應頭,可是不返回數據實體,用戶能夠根據響應頭信息,肯定下一步操做。
用響應頭的 response.expectedContentLength 能夠獲取文件數據的大小。
同步方法是阻塞式的,一般只有 HEAD 方法(得到的數據不多,並且後續的下載會依賴)纔會使用同步方法。在截取網絡數據的時候,最好使用同步方法,並且若是頻率過高,須要增長延時,不然會被服務器給加入黑名單。
二、文件下載方法:
1) 使用 GET 數據請求方法,數據請求完成後,將數據手動寫入文件中。
2) 使用專門用於下載的 GET 方法,數據請求完成後,將會自動寫入指定文件中。
三、文件本地保存方法:
四、文件斷點下載步驟:
3) 根據本地文件的長度,從對應 "偏移" 位置開始下載:
bytes=-x 從 文件開始下載,下載 x 字節
如:[urlRequest setValue:[NSString stringWithFormat:@"bytes=%lld-", offset] forHTTPHeaderField:@"Range"];
五、文件下載設置:
1) NSURLConnection:
代理方法默認都是在主線程上執行的,會對界面產生卡頓。
爲了讓鏈接工做正常,調用線程的運行循環必須在默認的運行循環模式下。
若是要讓 NSURLConnection 實如今後臺線程回調代理方法,須要在後臺線程啓動 NSURLConnection,並啓動後臺線程的運行循環,NSURLConnection 執行完畢後,會自動中止後臺線程的運行循環。
2) NSURLSession:
若是顯示比較大的圖片,NSURLSession 能夠利用磁盤緩存直接下載到本地,不會形成內存佔用太大。
下載任務的特色可讓程序員只關心解壓縮的工做。
3) 啓動子線程的運行循環方法:
CFRunLoopRun(); // NSRunLoop 只能啓動,沒有提供中止的接口 [[NSRunLoop currentRunLoop] run];
六、塊代碼回調:
1) Block 的屬性定義:
2) 網絡 block 回調的幾個 "約定":
AFN/SDWebImage 等第三方框架,都是這麼作的。
3> 失敗的回調,能夠在主線程,也能夠在後臺線程
Objective-C
NSURLConnection 同步請求
// 設置網絡接口 NSURL *url1 = [NSURL URLWithString:@"http://192.168.88.200:8080/MJServer/video?type=JSON"]; // 建立同步網絡請求 NSData *syncNetData1 = [NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:url1] returningResponse:nil error:NULL];
NSData 同步請求
// 設置網絡接口 NSURL *url2 = [NSURL URLWithString:@"http://192.168.88.200:8080/MJServer/video?type=JSON"]; // 建立同步網絡請求 NSData *syncNetData2 = [NSData dataWithContentsOfURL:url2];
NSString 同步請求
// 設置網絡接口 NSURL *url3 = [NSURL URLWithString:@"http://192.168.88.200:8080/MJServer/video?type=JSON"]; // 建立同步網絡請求 NSString *syncNetString = [NSString stringWithContentsOfURL:url3 encoding:NSUTF8StringEncoding error:nil];
WebView 同步請求
// 設置網絡接口 NSURL *url4 = [NSURL URLWithString:@"http://192.168.88.200:8080/MJServer"]; // 建立同步網絡請求 [self.webView loadRequest:[NSURLRequest requestWithURL:url4]];
Swift
NSURLConnection 同步請求
// 設置網絡接口 let url1 = NSURL(string: "http://192.168.88.200:8080/MJServer/video?type=JSON") // 建立同步網絡請求 let syncNetData1 = try! NSURLConnection.sendSynchronousRequest(NSURLRequest(URL: url1!), returningResponse: nil)
NSData 同步請求
// 設置網絡接口 let url2 = NSURL(string: "http://192.168.88.200:8080/MJServer/video?type=JSON") // 建立同步網絡請求 let syncNetData2 = NSData(contentsOfURL: url2!)
NSString 同步請求
// 設置網絡接口 let url3 = NSURL(string: "http://192.168.88.200:8080/MJServer/video?type=JSON") // 建立同步網絡請求 let syncNetString = try! NSString(contentsOfURL: url3!, encoding: NSUTF8StringEncoding)
WebView 同步請求
// 設置網絡接口 let url4 = NSURL(string: "http://192.168.88.200:8080/MJServer") // 建立同步網絡請求 self.webView.loadRequest(NSURLRequest(URL: url4!))
Objective-C
// 設置網絡接口 NSURL *url = [NSURL URLWithString:@"http://192.168.88.200:8080/MJServer/video"]; // 建立請求 NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url]; // 設置請求體(請求參數) urlRequest.HTTPBody = [@"type=JSON" dataUsingEncoding:NSUTF8StringEncoding]; // 設置請求方式 urlRequest.HTTPMethod = @"POST"; // 建立同步連接 NSData *syncNetData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:nil error:nil];
Swift
// 設置網絡接口 let url = NSURL(string: "http://192.168.88.200:8080/MJServer/video") // 建立請求 let urlRequest = NSMutableURLRequest(URL: url!) // 設置請求體(請求參數) urlRequest.HTTPBody = "type=JSON".dataUsingEncoding(NSUTF8StringEncoding) // 設置請求方式 urlRequest.HTTPMethod = "POST" // 建立同步連接 let syncNetData = try? NSURLConnection.sendSynchronousRequest(urlRequest, returningResponse: nil)
Objective-C
// 設置網絡接口 NSURL *url = [NSURL URLWithString:@"http://192.168.88.200:8080/MJServer/video?type=XML"]; // 建立異步網絡請求 [NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:url] queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { }];
Swift
// 設置網絡接口 let url = NSURL(string: "http://192.168.88.200:8080/MJServer/video?type=XML") // 建立異步網絡請求 NSURLConnection.sendAsynchronousRequest(NSURLRequest(URL: url!), queue: NSOperationQueue.mainQueue()) { (response:NSURLResponse?, data:NSData?, connectionError:NSError?) in }
Objective-C
// 設置網絡接口 NSURL *url = [NSURL URLWithString:@"http://192.168.88.200:8080/MJServer/video"]; // 建立請求 NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url]; // 設置請求體(請求參數) urlRequest.HTTPBody = [@"type=XML" dataUsingEncoding:NSUTF8StringEncoding]; // 設置請求方式 urlRequest.HTTPMethod = @"POST"; // 建立異步鏈接 [NSURLConnection sendAsynchronousRequest:urlRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { }];
Swift
// 設置網絡接口 let url = NSURL(string: "http://192.168.88.200:8080/MJServer/video") // 建立請求 let urlRequest = NSMutableURLRequest(URL: url!) // 設置請求體(請求參數) urlRequest.HTTPBody = "type=XML".dataUsingEncoding(NSUTF8StringEncoding) // 設置請求方式 urlRequest.HTTPMethod = "POST" // 建立異步網絡請求 NSURLConnection.sendAsynchronousRequest(urlRequest, queue: NSOperationQueue.mainQueue()) { (response:NSURLResponse?, data:NSData?, connectionError:NSError?) in }
Objective-C
// 設置網絡接口 NSURL *url = [NSURL URLWithString:@"http://192.168.88.200/demo.json"]; // 建立網絡請求 NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:15.0]; // 發送網絡鏈接 [[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { /* 網絡請求完成,處理請求結果,error != nil || data == nil 請求失敗。 */ // 錯誤處理的標準代碼 - 有的時候,沒有錯誤,可是也獲取不到數據 if (error != nil || data == nil) { // 不要告訴用戶太準確的錯誤信息 NSLog(@"您的網絡不給力,請稍候再試 !"); return; } // 請求數據解析 id result = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL]; NSLog(@"網絡請求成功 %@", result); }] resume];
Objective-C
單文件上傳
// 設置網絡接口 NSURL *url = [NSURL URLWithString:@"http://192.168.88.200/upload/upload.php"]; // 建立網絡請求 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; request.HTTPMethod = @"POST"; // 設置請求頭 #define boundary @"uploadBoundary" [request setValue:[NSString stringWithFormat:@"multipart/form-data; charset=utf-8; boundary=%@", boundary] forHTTPHeaderField:@"Content-Type"]; // 設置上傳的文件數據 NSMutableData *formDataM = [NSMutableData data]; // 添加文件 [formDataM appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; [formDataM appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", @"userfile", @"test.jpg"] dataUsingEncoding:NSUTF8StringEncoding]]; [formDataM appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n", @"image/jpeg"] dataUsingEncoding:NSUTF8StringEncoding]]; [formDataM appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; // 本地待上傳的文件 [formDataM appendData:[NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"HQ_0005" ofType:@"jpg"]]]; [formDataM appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; // 添加文本 [formDataM appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; [formDataM appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n%@\r\n", @"username", @"qian"] dataUsingEncoding:NSUTF8StringEncoding]]; // 添加結束分隔符 [formDataM appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; [[[NSURLSession sharedSession] uploadTaskWithRequest:request fromData:formDataM completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { if (error != nil || data == nil) return; id result = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL]; [self refreshUI:result]; }] resume];
單文件上傳簡單封裝
// NSData+FormData.m 。。。。。 // 設置上傳的文件數據 #define boundary @"uploadBoundary" NSMutableData *formDataM = [NSMutableData data]; [formDataM q_setHttpHeaderFieldWithRequest:request fileBoundary:boundary]; // 設置請求頭 [formDataM q_appendPartWithFileURL:[NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"HQ_0005" ofType:@"jpg"]] fileBoundary:boundary name:@"userfile" fileName:nil mimeType:nil]; // 添加文件 [formDataM q_appendPartWithText:@"qian" textName:@"username" fileBoundary:boundary]; // 添加文本 [formDataM q_appendPartEndingWithFileBoundary:boundary]; // 添加結束分隔符
單文件上傳封裝
// NSData+FormData.m 。。。。。 // 設置上傳的文件數據 // 指定文件數據方式 NSData *filedata = [[NSData alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"HQ_0003" ofType:@"jpg"]]; NSData *formData = [NSData q_formDataWithRequest:request fileData:filedata name:@"userfile" fileName:@"HQ_0003.jpg" mimeType:@"image/jpeg"]; NSData *formData = [NSData q_formDataWithRequest:request text:@"qian" textName:@"username" fileData:filedata name:@"userfile" fileName:@"HQ_0003.jpg" mimeType:@"image/jpeg"]; // 指定文件路徑方式 NSURL *fileURL = [NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"HQ_0005" ofType:@"jpg"]]; NSData *formData = [NSData q_formDataWithRequest:request fileURL:fileURL name:@"userfile" fileName:@"test.jpg" mimeType:@"image/jpeg"]; NSData *formData = [NSData q_formDataWithRequest:request text:@"qian" textName:@"username" fileURL:fileURL name:@"userfile" fileName:@"test.jpg" mimeType:@"image/jpeg"];
多文件上傳
// 設置網絡接口 NSURL *url = [NSURL URLWithString:@"http://192.168.88.200/upload/upload-m.php"]; // 建立網絡請求 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; request.HTTPMethod = @"POST"; // 設置請求頭 #define boundary @"uploadBoundary" [request setValue:[NSString stringWithFormat:@"multipart/form-data; charset=utf-8; boundary=%@", boundary] forHTTPHeaderField:@"Content-Type"]; // 設置上傳的文件數據 NSMutableData *formDataM = [NSMutableData data]; // 添加第一個文件 [formDataM appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; [formDataM appendData:[[NSString stringWithFormat:@"Content-Disposition:form-data; name=\"%@\"; filename=\"%@\"\r\n", @"userfile[]", @"test1.jpg"] dataUsingEncoding:NSUTF8StringEncoding]]; [formDataM appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n", @"image/jpeg"] dataUsingEncoding:NSUTF8StringEncoding]]; [formDataM appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; [formDataM appendData:[NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"HQ_0003" ofType:@"jpg"]]]; [formDataM appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; // 添加第二個文件 [formDataM appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; [formDataM appendData:[[NSString stringWithFormat:@"Content-Disposition:form-data; name=\"%@\"; filename=\"%@\"\r\n", @"userfile[]", @"test2.jpg"] dataUsingEncoding:NSUTF8StringEncoding]]; [formDataM appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n", @"image/jpeg"] dataUsingEncoding:NSUTF8StringEncoding]]; [formDataM appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; [formDataM appendData:[NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"HQ_0005" ofType:@"jpg"]]]; [formDataM appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; // 添加文本 [formDataM appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; [formDataM appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n%@\r\n", @"username", @"qian"] dataUsingEncoding:NSUTF8StringEncoding]]; // 添加結束分隔符 [formDataM appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; [[[NSURLSession sharedSession] uploadTaskWithRequest:request fromData:formDataM completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { if (error != nil || data == nil) return; id result = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL]; [self refreshUI:result]; }] resume];
多文件上傳封裝
// NSData+FormData.m 。。。。。 // 設置上傳的文件數據 // 指定文件數據方式 NSData *filedata1 = [[NSData alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"HQ_0003" ofType:@"jpg"]]; NSData *filedata2 = [[NSData alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"HQ_0005" ofType:@"jpg"]]; NSData *formData = [NSData q_formDataWithRequest:request fileDatas:@[filedata1, filedata2] name:@"userfile[]" fileNames:@[@"test1.jpg", @"test2.jpg"] mimeTypes:@[@"image/jpeg", [NSNull null]]]; NSData *formData = [NSData q_formDataWithRequest:request texts:@[@"qian"] textNames:@[@"username"] fileDatas:@[filedata1, filedata2] name:@"userfile[]" fileNames:@[@"test1.jpg", @"test2.jpg"] mimeTypes:@[@"image/jpeg", [NSNull null]]]; // 指定文件路徑方式 NSURL *fileURL1 = [NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"HQ_0003" ofType:@"jpg"]]; NSURL *fileURL2 = [NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"HQ_0005" ofType:@"jpg"]]; NSData *formData = [NSData q_formDataWithRequest:request fileURLs:@[fileURL1, fileURL2] name:@"userfile[]" fileNames:@[@"test1.jpg", [NSNull null]] mimeTypes:@[@"image/jpeg", [NSNull null]]]; NSData *formData = [NSData q_formDataWithRequest:request texts:@[@"qian"] textNames:@[@"username"] fileURLs:@[fileURL1, fileURL2] name:@"userfile[]" fileNames:@[@"test1.jpg", [NSNull null]] mimeTypes:@[@"image/jpeg", [NSNull null]]];
Objective-C
獲取文件信息
// 設置網絡接口 NSURL *url = [NSURL URLWithString:@"http://192.168.88.200/download/file/minion_01.mp4"]; // 建立網絡請求 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; request.HTTPMethod = @"HEAD"; [[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { if (error != nil || data == nil) return; NSLog(@"要下載文件的長度 %tu", response.expectedContentLength); }] resume];
基本下載
// 設置請求路徑 NSURL *url = [NSURL URLWithString:@"http://192.168.88.200/download/file/minion_01.mp4"]; // 建立請求對象 NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url]; // 建立會話對象 NSURLSession *urlSession = [NSURLSession sharedSession]; NSURLSessionDownloadTask *urlSessionDownloadTask = [urlSession downloadTaskWithRequest:urlRequest completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) { if (error == nil) { // 設置下載的文件存儲路徑 NSString *documentsDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0] stringByAppendingPathComponent:response.suggestedFilename]; // 處理下載的數據 [[NSFileManager defaultManager] copyItemAtPath:location.path toPath:documentsDirPath error:nil]; } }]; // 執行任務 [urlSessionDownloadTask resume];
Objective-C
GET 請求
// 設置文件位置 NSURL *url = [NSURL URLWithString:@"http://192.168.88.200/uploads/123.png"]; [[[NSURLSession sharedSession] downloadTaskWithURL:url completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) { // 將下載的文件讀取到二進制數據 NSData *data = [NSData dataWithContentsOfURL:location]; dispatch_async(dispatch_get_main_queue(), ^{ // 若是顯示比較大的圖片,NSURLSession 能夠利用 self.iconView.image = [UIImage imageWithData:data]; }); // 磁盤緩存直接下載到本地,不會形成內存佔用太大 }] resume];
PUT 請求
// 本地要上傳的文件 NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@"minion.mp4" withExtension:nil]; // 123.mp4 保存到服務器的文件名 NSURL *url = [NSURL URLWithString:@"http://192.168.88.200/uploads/123.mp4"]; // PUT 文件上傳,以文件的方式直接寫入到 WebDav 服務器中 NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url]; urlRequest.HTTPMethod = @"PUT"; // 服務器驗證,用戶訪問名和密碼 [urlRequest setValue:[@"admin:adminpasswd" q_basic64AuthEncode] forHTTPHeaderField:@"Authorization"]; [[[NSURLSession sharedSession] uploadTaskWithRequest:urlRequest fromFile:fileURL completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { NSLog(@"%@ %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding], response); }] resume];
DELETE 請求
// 要刪除的文件完成路徑 NSURL *url = [NSURL URLWithString:@"http://192.168.88.200/uploads/123.mp4"]; // DELETE 文件刪除 NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url]; urlRequest.HTTPMethod = @"DELETE"; // 服務器驗證,用戶訪問名和密碼 [urlRequest setValue:[@"admin:adminpasswd" q_basic64AuthEncode] forHTTPHeaderField:@"Authorization"]; [[[NSURLSession sharedSession] dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { NSLog(@"%@ %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding], response); }] resume];