POST


XCode 7 新增加的百分号转义
urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];

 重点:
1,单个文件上传(四个步骤) 2.请求体格式
{
   为什么要上传文件:
  
- 以前很多服务器对上传文件的大小有限制,PHP限制是2M
- 目前很多服务器不仅不限制大小,而且鼓励上传多个文件
- 云服务的普及
- 软件希望获得更多的用户数据

提示:add 的目录是用来保存上传文件的,需要设置访问权限

<1>文件上传使用POST方法.

<1> 文件上传使用 POST 方法.
   
   
// 请求为可变请求
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
   
// 制定请求方法为 POST
    request.HTTPMethod =
@"POST";
   
    <
2> 设置请求头,告诉服务器请求体中的内容包含文件参数.
    [request setValue:
@"multipart/form-data; boundary=kBoundary" forHTTPHeaderField:@"Content-Type"];
   
    <
3> 设置请求体(注意:必须严格按照格式设置).
    {
       
// 上边界
        --boundary\r\n
        Content-Disposition: form-data; name=userfile; filename=
555\r\n
        Content-Type: application/json\r\n\r\n
       
       
       
文件内容的二进制数据
       
       
// 下边界
        \r\n--boundary--

}
注意1:请求体内容分为三个部分:

*上边界,告诉服务器要做数据上传,包含了服务器的接受字段name=userfile,文件在服务器中保存的名称filenname = 555以及上传文件的数据类型,apploction/json(需要严格按照字符串格式来设置)


* 上传文件的数据部分(二进制数据)

* 下边界部分,严格按照字符串格式来设置

上边界部分和下边界部分的字符串,最后都要转换成二进制数据,和文件部分的二进制数据拼接在一起,作为请求体发送服务器

 注意2:

* userfile =  负责上传文件脚本中的,字段名,开发的时候,可以咨询后端程序员
* filename = 将文件保存在服务器的文件名上
* content - Type :客户端告诉服务器上传文件的类型
注意3:
 
   * 每一行末尾需要有一定的 \r\n
   * 提示:有些服务器可以直接使用 \n,但是新浪微博如果使用 \n 上传文件,服务器会返回没有权限的错误!
       
    }

<4> 发送请求( NSURLConnection异步发送请求)
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
       
//
        NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
       
        NSLog(
@"%@",string);
    }];

重点2:
掌握多文件上传的数据格式 2. 学会封装多文件上传的方法{
   多文件上传和单文件上传的基本思路是一样的,,唯一的区别在于对请求体的封装

多文件的请求部分格式1{

多文件的请求体部分格式 1
    {
       
// 第一个文件参数的上边界
        \r\n--boundary\r\n
        Content-Disposition: form-data; name=userfile[]; filename=
美女\r\n
        Content-Type:image/jpeg\r\n\r\n
       
       
       
上传文件的二进制数据部分
       
       
// 第一个文件参数的下边界
        \r\n--boundary--

       
// 第二个文件参数的上边界
        \r\n--boundary\r\n
        Content-Disposition: form-data; name=userfile[]; filename=JSON\r\n
        Content-Type:text/plain\r\n\r\n
       
       
       
上传文件的二进制数据部分
       
// 第二个文件参数的下边界
        \r\n--boundary--
    }
    {
       
多文件上传的请求体格式2
       
       
// 上边界
       
// 第一个文件参数
        \r\n--boundary\r\n
        Content-Disposition: form-data; name=userfile[]; filename=
美女\r\n
        Content-Type:image/jpeg\r\n\r\n
       
       
       
上传文件的二进制数据部分
   
       
// 第二个文件参数
        \r\n--boundary\r\n
        Content-Disposition: form-data; name=userfile[]; filename=JSON\r\n
        Content-Type:text/plain\r\n\r\n
       
       
       
上传文件的二进制数据部分
       
       
// 下边界
        \r\n--boundary--
    }


}



}
重点:能够获取文件的MIMEType
{
   上传文件的时候,需要告诉服务器的文件类型(即Content - Type)这时,需要获取文件的MIMEType.

获取文件的MTMEType 放法,加载文件时,通过response 获取
{

        NSURLRequest *request = [NSURLRequest requestWithURL:url];
       
        NSURLResponse *response =
nil;
       
        [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:
NULL];
       
        NSLog(@"%@",response.MIMEType);

}
  response.MIMEType 即为 Content-Type 的类型.
   
   
如果不想告诉服务器具体的文件类型,可以使用这个 Content-Type : application/octet-stream(8进制流)
   
   
常见的 Content-Type 类型:
    {
        -
大类型/小类型
        - text/plain
        - image/jpg
        - image/png
        - image/gif
        - text/html
        - application/json
    }
}
重点: 学会拼接上传文件数据.
{
   * 有些服务器可以在上传文件的同时,提交一些文本内容给服务器
   *典型应用:
 
  <1>新浪微博: 上传图片的同时,发送一条微博信息!
  <2>购物评论: 购物商品之后发表评论的图片+评论内容!

多文件上传的数据格式3{

   Content-Type: multipart/form-data; boundary=boundary
       
       
// ------ 以下内容,是提供给服务器的二进制数据格式
        --boundary\r\n
        Content-Disposition: form-data; name=
"userfile[]"; filename="aaa.txt"\r\n
        Content-Type: application/octet-stream\r\n\r\n
       
       
文件二进制数据
        \r\n
        --boundary\r\n
        Content-Disposition: form-data; name=
"userfile[]"; filename="aaa副本.txt"\r\n
        Content-Type: application/octet-stream\r\n\r\n
       
       
文件二进制数据
        \r\n
        --boundary\r\n
       
// username 是脚本文件接收参数的名称
        Content-Disposition: form-data; name=
"username"\r\n\r\n
       
       
普通文本二进制数据
        \r\n
        --boundary--
       
// ------
       
        以上部分,是发送给服务器的二进制数据 的组成格式(示例)

}


}
如果在IOS中,要实现POST上传文件,需要按照上述格式,拼接数据

因为:格式是W3c 指定的标准格式,苹果没有做任何封装!其他语言,都做了封装!

以上三种数据拼接格式,需要大家了解并且能够自己会拼接一种

"第三方框架做文件上传:
   
    - AFN
能够同时实现上传"一个文件",有些格式的文件, AFN 无法上传!
    - ASI 能够同时实现上传多个文件,MRC,2012年就停止更新了,设计的目标平台, iOS 2.0/iOS 3.0 !

重点:了解RESTful设置风格
{
   为了简化开发流程,使开发更加直观,解读更加容易,现在有一种非常流行的设置风格——> RESTful设置风格

RESTful设计风格:

   主要用于后端开发,主要的表现形式为使用同一个URL不同的HTTP 访问方法,表达不同的语义{
示例: http:/\/\www.xxx.com/product/123
       
        -GET http:/\/\www.xxx.com/product/
123  语义:从服务器"获取"产品ID 123的产品信息.
       
        -POST http:/\/\www.xxx.com/product/
123  语义:在服务器"新增"产品ID 123的产品信息.
       
        *
提交二进制数据,需要提交一个 JSON 格式的二进制数据,后端程序员可以直接反序列化,得到 JSON 中得字典信息.
        * POST JSON

        -PUT http:/\/\www.xxx.com/product/
123  语义:在服务器"修改"产品ID 123的产品信息.

        -DELETE http:/\/\www.xxx.com/product/
123  语义:从服务器"删除"产品ID 123的产品信息.

        RESTful
设计风格目前在国际上非常流行,国内也逐渐开始普及.
       
        作为前端程序员,只需要知道有这种设计风格就可以.



}

}
重点:AFN监测网络状态 2.了解Reachability 监测网络状态
{
   1. AFN 监测网络状态

// 创建 网络状态管理者
        AFNetworkReachabilityManager *mgr = [AFNetworkReachabilityManager sharedManager];
       
       
// 监测网络状态的改变
        [mgr setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
           
// 当网络状态发生改变的时候调用这个block
           
switch (status) {
               
case AFNetworkReachabilityStatusReachableViaWiFi:
                    NSLog(
@"WIFI网络");
                   
break;
                   
               
case AFNetworkReachabilityStatusReachableViaWWAN:
                    NSLog(
@"蜂窝网络");
                   
break;
                   
               
case AFNetworkReachabilityStatusNotReachable:
                    NSLog(
@"没有网络");
                   
break;
                   
               
case AFNetworkReachabilityStatusUnknown:
                    NSLog(
@"未知网络");
                   
break;
               
default:
                   
break;
            }
        }];
       
// 开始监控
        [mgr startMonitoring];
    }
   
2.Reachability 监测网络状态
    {
       
// 注册通知观察者,网络状态改变时,接收通知!
        [[NSNotificationCenter defaultCenter] addObserver:
self selector:@selector(InternetStatusChanged) name:kReachabilityChangedNotification object:nil];

       
// 控制器销毁时,移除通知观察者.
        -(
void)dealloc
        {
            [[NSNotificationCenter defaultCenter] removeObserver:
self];
        }
       
       
// 根据当前网络状态,做出不同的响应.
        - (
void)InternetStatusChanged
        {
            NSLog(
@"网络状态改变了");
           
           
if ([Reachability reachabilityForLocalWiFi].currentReachabilityStatus == ReachableViaWiFi) {
                NSLog(
@"Wifi 网络");
            }
           
if ([Reachability reachabilityForInternetConnection].currentReachabilityStatus == ReachableViaWWAN) {
                NSLog(
@"蜂窝移动网络");
            }
           
if ([Reachability reachabilityForInternetConnection].currentReachabilityStatus == NotReachable)
            {
                NSLog(
@"没有网络");
            }
        }
       
// 创建 Reachability 对象,开始监测网络状态的改变
        - (
void)MonitorInternetStatus
        {
            Reachability *CZReachability = [Reachability reachabilityForInternetConnection];
           
            [CZReachability startNotifier];
           
           
self.reachability = CZReachability;
        }

        - (
void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
        {
            [
self MonitorInternetStatus];
        }
    }
}

}














  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值