[iOS]http的表單請(qǐng)求

現(xiàn)在我們經(jīng)常用到請(qǐng)求數(shù)據(jù)的方式是http+json方式,但是,在某些情況下,后臺(tái)提供給你的方式是http的表單請(qǐng)求方式,今天就總結(jié)一下表單請(qǐng)求方式的實(shí)現(xiàn)。
先來(lái)看一下表單的一般形式:

3491AF42-5C81-448B-B7BB-5C776C551507.png

在表單中,我們需要注意的有以下幾點(diǎn):

  • 1.我們需要自己設(shè)置Content-Type和Content-Length
  • 2.在表單中,boundary是一個(gè)很重要的東西,他可以是一個(gè)隨機(jī)的字符串,它是將參數(shù)隔開(kāi)的標(biāo)志,但需要注意的是,這個(gè)標(biāo)志在整個(gè)表單中必須一致
  • 3.我們?cè)谠O(shè)置參數(shù)時(shí),需要指定Content-Disposition,其中,name為參數(shù)對(duì)于的key值。如果參數(shù)為文件格式,同時(shí)還要指定filename以及Content-Type
  • 4.其中最重要的一點(diǎn),就是在設(shè)置參數(shù)的value時(shí),必須在值之前加入一個(gè)換行。同時(shí),在http中,換行為\r\n
  • 5.參數(shù)的分隔是以"--"拼接上boundary,然后拼接上"\r\n"來(lái)實(shí)現(xiàn)的,同時(shí),在所有參數(shù)結(jié)束后,需要以"--"拼接boundary再拼接"--"來(lái)結(jié)束。

接下來(lái)寫(xiě)一個(gè)簡(jiǎn)短的例子來(lái)記錄用法,在這個(gè)例子中,接口需要傳入兩個(gè)參數(shù),一個(gè)為簡(jiǎn)單的參數(shù),另一個(gè)為文件參數(shù)。

  • 1.我們可以自己拼接出表單形式
    //接口地址
    NSString *path = kURL;
    //boundary
    NSString *theBoundary = @"myBoundary";
    //訪問(wèn)請(qǐng)求
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:path]];
    request.HTTPMethod = @"POST";
    //用來(lái)拼接參數(shù)
    NSMutableData *data = [NSMutableData data];
    //拼接第一個(gè)參數(shù)
    [data appendData:[[NSString stringWithFormat:@"--%@\r\n", theBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
    //拼接參數(shù)名
    [data appendData:[@"Content-Disposition:form-data;name=\"uid\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    //拼接參數(shù)值
    [data appendData:[@"11230953" dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    //拼接第二個(gè)參數(shù)
    [data appendData:[[NSString stringWithFormat:@"--%@\r\n", theBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
    //拼接參數(shù)名
    [data appendData:[@"Content-Disposition:form-data;name=\"file\";filename=\"myText.txt\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    //拼接文件類(lèi)型
    [data appendData:[@"Content-Type:text/plain" dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:[@"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    //拼接參數(shù)值
    [data appendData:[NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"myText" ofType:@"txt"]]];
    [data appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    //拼接結(jié)束標(biāo)志
    [data appendData:[[NSString stringWithFormat:@"--%@--", theBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
    
    request.HTTPBody = data;
    [request setValue:[NSString stringWithFormat:@"multipart/form-data;boundary=%@", theBoundary] forHTTPHeaderField:@"Content-Type"];
    [request setValue:[NSString stringWithFormat:@"%ld", data.length] forHTTPHeaderField:@"Content-Length"];
    
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
        NSLog(@"%@", dic);
    }];
    [dataTask resume];
  • 2.既然是網(wǎng)絡(luò)請(qǐng)求,就不能忘掉強(qiáng)大的AFN,AFN提供了表單的請(qǐng)求方法,下圖是AFN主頁(yè)所講:
C3875D2B-96D8-4BD3-8766-BBF0CB665228.png

我們可以用AFN來(lái)實(shí)現(xiàn)上述接口的傳參:

    NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:kURL parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        [formData appendPartWithFormData:[@"11230953" dataUsingEncoding:NSUTF8StringEncoding] name:@"uid"];
        [formData appendPartWithFileData:[NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"myText" ofType:@"txt"]] name:@"file" fileName:@"myText.txt" mimeType:@"text/plain"];
    } error:nil];
    
    
    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
    
    NSURLSessionUploadTask *uploadTask;
    uploadTask = [manager
                  uploadTaskWithStreamedRequest:request
                  progress:^(NSProgress * _Nonnull uploadProgress) {
                  }
                  completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
                      if (error) {
                          NSLog(@"Error: %@", error);
                      } else {
                          NSLog(@"%@ %@", response, responseObject);
                      }
                  }];
    
    [uploadTask resume];

注意,有時(shí)可能會(huì)報(bào)以下錯(cuò)誤:

B21632C2-15F0-4AF7-A480-38154DB5B320.png

這里我們可以去工程中查找AFN的源碼,其中有一個(gè)文件為:AFURLResponseSerialization.m,我們?cè)诘?20行左右做一些修改,將所缺少類(lèi)型加上即可:
修改前:

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

修改后:

    self.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/plain", nil];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,431評(píng)論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,637評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 178,555評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,900評(píng)論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,629評(píng)論 6 412
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,976評(píng)論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,976評(píng)論 3 448
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 43,139評(píng)論 0 290
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,686評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,411評(píng)論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,641評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,129評(píng)論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,820評(píng)論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 35,233評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 36,567評(píng)論 1 295
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,362評(píng)論 3 400
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,604評(píng)論 2 380

推薦閱讀更多精彩內(nèi)容