對於iOS端的特殊性 不用form-data(也就是表單)傳流 直接用post傳參的形式傳遞流 自己的一點感悟和小結


不用form-data(也就是表單)傳流  直接用post傳參的形式傳遞流

這里面我們介紹的是第三方框架  AFNetworking:

AFNetworking是一個輕量級的iOS網絡通信類庫。它建立在NSURLConnection和NSOperation等類庫的基礎上,讓很多網絡通信功能的實現變得十分簡單。它支持HTTP請求和基於REST的網絡服務(包括GET、POST、 PUT、DELETE等)。支持ARC,不帶上這句感覺沒頭沒尾的。

1.首先   所有的網絡請求,均有manager發起 

        AFHTTPRequestOperationManager *manager=[AFHTTPRequestOperationManager manager];        

        manager.requestSerializer = [AFJSONRequestSerializer serializer];

        manager.responseSerializer = [AFJSONResponseSerializer serializer];

        需要注意的是,默認提交請求的數據是二進制的,返回格式是JSON 

  

    1> 如果提交數據是JSON的,需要將請求格式設置為AFJSONRequestSerializer 

    2> 如果返回格式不是JSON的, 

2. 請求格式 

  

     AFHTTPRequestSerializer            二進制格式 

     AFJSONRequestSerializer            JSON 

     AFPropertyListRequestSerializer    PList(是一種特殊的XML,解析起來相對容易) 

 

    說到這里就說下自己陷入的誤區   iOS客戶端這塊是直接傳遞流的也就是(NSData)

    但是AF的  AFHTTPRequestSerializer  和  AFJSONRequestSerializer是傳遞有區分  

    AFHTTPRequestSerializer的傳遞 在底層又對  參數和參數值進行了一次Url編碼  

    >>>>>>[mutableRequest setHTTPBody:[query dataUsingEncoding:self.stringEncoding]];

                                   

    AFJSONRequestSerializer的傳遞 則是在底層將 參數(一般情況下我們傳遞的是字典類型 也就是java中的map形式)轉化為了NSData類型進行傳遞

    >>>>>>[mutableRequest setHTTPBody:[NSJSONSerialization dataWithJSONObject:parameters options:self.writingOptions error:error]];

                  由於此時我的項目要求直接傳遞NSData(id+手機號+圖片流)此時的NSData是用NSMutableData 所以在底層 就不需要再次的轉化一次data

                  此時我修改代碼為

                  >>>>>>[mutableRequest setHTTPBody:parameters];

                  這樣我就可以直接用json形式直接傳遞服務端所需要的NSData  沒有包含form-data里面所攜帶的參數 因為這些參數服務端那邊代碼解析會出現問題

                  我猜測服務端用的不是主流的解析框架

    

 

     介紹完了請求對象方式屬性  下面來說下傳遞參數的屬性

     一般的網絡請求分為2種也就是mimeType的2種類型

     1.application/x-www-form-urlencoded

     2.multipart/form-data(最初的 http 協議中,沒有上傳文件方面的功能。rfc1867為http協議添加了這個功能)也就是Multipart協議

     >>>>>>絕大部分 http server ,包括 tomcat ,已經支持此協議,可接受發送來的文件。各種網頁程序,如 php, asp, jsp 中,對於上傳文件已經做了很好的封裝

                  但是我猜測我們服務端並未使用這種方式

     >>>>>>我們先查看這個協議的結構       以下是別人的概述:

            --${bound} // 該bound表示pdf的文件名
            Content-Disposition: form-data; name="Filename"
 
            HTTP.pdf
            --${bound} // 該bound表示pdf的文件內容 
            Content-Disposition: form-data; name="file000"; filename="HTTP協議詳解.pdf"
            Content-Type: application/octet-stream
 
            %PDF-1.5
            file content
            %%EOF
 
            --${bound} // 該bound表示字符串
            Content-Disposition: form-data; name="Upload"
 
            Submit Query
            --${bound}—// 表示body結束了
 >>>>>>>> request是由三個部分組成的:①請求行(request-line) ②請求頭(headers) ③請求體(request body)

                                                       構建multipart請求行      就是POST。

                                                       構建multipart請求頭

                                                       @property (nonatomic, copy) NSString *boundary; // multipart協議中的分割符

                                                        boundary是用來分割不同數據內容的,其實就是上面舉的那個例子中的${bound}

                                                        AFNetworking自定義了個函數創建boundary字符串  

                                                        1.如果是開頭分隔符的,那么只需在分隔符結尾加一個換行符

                                                          2.如果是中間部分分隔符,那么需要分隔符前面和結尾都加換行符

                                                                           3.如果是末尾,還得使用--分隔符--作為請求體的結束標志

                                                                           他的作用除了設置Content-Type外,在設置Content-Length時使用的[self.bodyStream contentLength]中會使用到                                                                                         boundary的    

       我的經歷就是當時用的是form-data傳遞  但是可能后台沒用主流解析框架    導致 解析不出我所傳遞的 NSData 然后顯示的解析除了   --boundary+開頭的字段

       所以此時我就果斷拋棄了使用 form-data     

       改用application/x-www-form-urlencoded的網絡和AFJSONRequestSerializer(修改底層不用再次轉化一次data)結合的方式  直接將data類型的傳遞至服務端

       至此  自己的坑比生涯結束

       有些寫的不太詳細   有什么不對  還望各位指點  謝謝

    

 

 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM