美文网首页
POST上传

POST上传

作者: 蓝心儿的蓝色之旅 | 来源:发表于2015-12-19 23:20 被阅读1396次

    /*----------------- 01 POST上传单个文件 -----------------*/

    重点:1.单个文件上传(四个步骤) 2.设置请求体格式

    {

    为什么要上传文件:

    - 以前很多服务器对上传文件的大小有限制,PHP 限制是 2M

    - 目前很多服务器不仅不限制大小,而且鼓励上传多个文件!

    - 云服务器的普及!

    - 软件商希望获得更多的用户数据!

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

    <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,文件在服务器中保存的名称filename=555,以及上传文件的数据类型 application/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);

    }];

    }

    /*------------------------- 02 多文件上传 ------------------------*/

    重点:1.掌握多文件上传的数据格式 2.学会封装多文件上传的方法

    {

    多文件上传和单文件上传的基本思路是一样的,唯一的区别在于对请求体的封装.

    多文件的请求体部分格式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--

    }

    }

    /*--------------------- 03 获取文件的 MIMEType ---------------------*/

    重点: 能够获取文件的 MIMEType.

    {

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

    获取文件的 MIMEType 方法:加载文件时,通过 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

    }

    }

    /*------------------- 04 多文件 + 普通文本上传 -----------------------*/

    重点: 学会拼接上传文件数据.

    {

    * 有些服务器可以在上传文件的同时,提交一些文本内容给服务器

    * 典型应用:

    <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 !

    }

    /*---------------------- 05 RESTful设计风格 ----------------------*/

    重点: 了解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设计风格目前在国际上非常流行,国内也逐渐开始普及.

    作为前端程序员,只需要知道有这种设计风格就可以.

    }

    }

    /*-------------------- 06 AFN 上传文件 ---------------------*/

    重点: 掌握 AFN 上传文件的方法

    {   

     // 1. 创建管理者

        AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];       

     // 2. 发送请求  

      [mgr POST:@"http://localhost/upload/upload.php" parameters:nil constructingBodyWithBlock:^(idformData) {

    // formData :设置上传文件所需要的参数,两种上传方法:

    // <1> 通过本地文件的 url 上传

    {

    NSString *fromFile = @"/Users/likaining/Desktop/meinv.jpg";

    NSURL *url = [NSURL URLWithString:@"file:///Users/likaining/Desktop/meinv.jpg"];

    // url :需要上传文件的文件路径

    // name :服务器接收的文件名.

    // fileName: 文件在服务器中保存的名字

    // mimeType : 文件类型

    [formData appendPartWithFileURL:url name:@"userfile" fileName:@"meinv" mimeType:@"image/jpg" error:NULL];

    }

    // <2> 通过文件的 二进制数据 上传

    {

    NSData *data = [NSData dataWithContentsOfFile:zipFile];

    [formData appendPartWithFileData:data name:@"userfile" fileName:@"meinv.zip" mimeType:@"gzip"];

    }

    } success:^(AFHTTPRequestOperation *operation, id responseObject) {

    // 上传成功之后的回调

    NSLog(@"%@",responseObject);

    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {

    //  上传失败之后的回调

    NSLog(@"失败");

    }];

    }

    /*--------------------- 07 监测网络状态 ---------------------*/

    重点: 1.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];

    }

    }

    }

    相关文章

      网友评论

          本文标题:POST上传

          本文链接:https://www.haomeiwen.com/subject/nixmhttx.html