美文网首页
(转)POST请求的两种格式

(转)POST请求的两种格式

作者: Flora_HAHA | 来源:发表于2019-04-22 10:30 被阅读0次

    https://blog.csdn.net/peterwon/article/details/52093865
    https://www.jianshu.com/p/f0a9c47167fd

    POST请求的两种格式
    1、同步请求可以从因特网请求数据,一旦发送同步请求,程序将停止用户交互,直至服务器返回数据完成,才可以进行下一步操作,
    2、异步请求不会阻塞主线程,而会建立一个新的线程来操作,用户发出异步请求后,依然可以对UI进行操作,程序可以继续运行
    3、GET请求,将参数直接写在访问路径上。操作简单,不过容易被外界看到,安全性不高,地址最多255字节;
    4、POST请求,将参数放到body里面。POST请求操作相对复杂,需要将参数和地址分开,不过安全性高,参数放在body里面,不易被捕获。

    GET是比较简单的请求方式,在URL中直接就包含了要发送的所有参数。
    POST可以这样理解主要用于向服务器上传数据,简单一点的是上传文字,复杂一点的是上传图片声音等等。那么对于这种需求显然如果使用GET的话,那么这URL未免会太长。因此有POST方式的存在,可以在基本的URL的情况下,再附加一个数据包,包含要上传的数据,然后和URL一起发送给服务器。
    POST方法有两种格式,一种是基本的格式,一般用于发送文字信息。

    Post请求基本格式如下:
    POST /login.asp HTTP/1.1
    Host: www.example.com
    Content-Type: application/x-www-form-urlencoded

     /* * 文件上传的时候需要设置请求头中Content-Type类型, 必须使用URL编码,
         application/x-www-form-urlencoded:默认值,发送前对所有发送数据进行url编码,支持浏览器访问,通常文本内容提交常用这种方式。
         multipart/form-data:多部分表单数据,支持浏览器访问,不进行任何编码,通常用于文件传输(此时传递的是二进制数据) 。
         text/plain:普通文本数据类型,支持浏览器访问,发送前其中的空格替换为“+”,但是不对特殊字符编码。
         application/json:json数据类型,浏览器访问不支持 。
         text/xml:xml数据类型,浏览器访问不支持。
         multipart/form-data 必须进行设置,
         */
    

    Content-Length: 35
    username=wantsoft&password=password //post的数据
    另一种是multipart/form-data,格式如下
    POST /upload_file/UploadFile HTTP/1.1
    Accept: text/plain, /
    Accept-Language: zh-cn
    Host: www.example.com
    Content-Type:multipart/form-data;boundary=—————————7d33a816d302b6
    User-Agent: Mozilla/4.0 (compatible; OpenOffice.org)
    Content-Length: 424
    Connection: Keep-Alive —————————–7d33a816d302b6
    Content-Disposition:form-data;
    name=”userfile”;
    filename=”userfile”
    Content-Type: application/octet-stream abbXXXccc
    —————————–7d33a816d302b6
    Content-Disposition: form-data;
    name=”text1” foo
    —————————–7d33a816d302b6
    Content-Disposition: form-data;
    name=”password1” bar
    —————————–7d33a816d302b6–
    看起来比较复杂,其实就是把请求数据通过分界线也就是Boundary分开,至于开头的一些内容,很多都是默认,无需考虑。

    // 编码方式  
    // 1. Content-type: multipart/form-data, boundary=AaB03x;  
    // 2. 分割符号  --boundary  
    
    // 请求的内容类型 配置 说明  
    // 3. Content-disposition  
    // 4 body实体  
    // 5. 尾部分隔符--boundary--  
    // 头  
    NSString *head = @"Content-type: multipart/form-data, boundary=AaB03x\n\n";  
    NSString *boundary = @"AaB03x";  
    NSString *headBoundary = [NSString stringWithFormat:@"--%@",boundary];  
    NSString *endBoundary = [NSString stringWithFormat:@"--%@--",boundary]; 
     
    // 封装网络请求  
    NSString *contentString = @"content-disposition: form-data; name=\"pic\"; filename=\"star_pressed.png\"Content-Type: image/png\n\n";  
    
    // 请求  
    NSURL *url = [NSURL URLWithString:urlString];  
    
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];  
    
    [request setHTTPMethod:@"POST"];  
    
    // 设置body  
    NSData *fileData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"star_pressed.png" ofType:nil]];  
    
    
    // 设置总的请求体  
    NSMutableData *data = [NSMutableData data];  
    
    // 报文头 = 头 + 头分隔符 + 内容说明 + body实体 + 尾分隔符  
    [data appendData:[head dataUsingEncoding:NSUTF8StringEncoding]]; 
    [data appendData:[headBoundary dataUsingEncoding:NSUTF8StringEncoding]];
    [data appendData:[contentString dataUsingEncoding:NSUTF8StringEncoding]];  
    [data appendData:fileData]; 
    
    // 其实如果要请求多个数据,大括号中三个是需要不停的拼接的,而head 和 endBoundary是只需要追加在最前和最后,然后设置在请求体中。! 
    // 不过不要忘记了 设置请求数据类型哦。。 
    // 一般文字就是application/x-www/form-urlencoded 图片等就用这个了。。multipart/form-data,其实不简单。。。。。。 
    // 对了 还一定要注意空格和换行,到用到的时候看一下格式!!!!
    data appendData:[endBoundary dataUsingEncoding:NSUTF8StringEncoding]];  
    
    // 设置请求体  
    [request setHTTPBody:data];  
    
    // 设置请求头,01 - 设置请求数据的长度  
    [request setValue:[NSString stringWithFormat:@"%lu",(unsigned long)data.length] forHTTPHeaderField:@"Content-Length"];  
    
    // 02 - 设置请求数据的类型  
    [request addValue:@"multipart/form-data" forHTTPHeaderField:@"Content-Type"];  
    
    // 4.创建连接,发送请求  
    _urlConnection  = [[NSURLConnection alloc] initWithRequest:request delegate:self];  
    
    //      重要例子  
    //    Content-type: multipart/form-data, boundary=AaB03x  
    //  
    //    --AaB03x  
    //    content-disposition: form-data; name="field1"  
    //  
    //    Hello Boris!  
    //    --AaB03x  
    //    content-disposition: form-data; name="pic"; filename="boris.png"  
    //    Content-Type: image/png  
    //  
    //    ... contents of boris.png ...  
    //    --AaB03x--  
    ////  
    //    第一行是指定了http post请求的编码方式为multipart/form-data(上传文件必须用这个)。  
    //    boundary=AaB03x说明了AaB03x为分界线。比如 --AaB03x 就是一个分界线的意思  
    //  
    //    content-disposition: form-data; name="field1"  
    //  
    //    Hello Boris!  
    //  
    //      这句话声明了请求中的一个字段的名称,如field1  以及字段的值,如Hello Boris!  
    //    这里类似form表单中的<input name="field1" type="text" value="Hello Boris!"/>  
    //    中间的空行是必须的。  
    //  
    //    不同的字段之间用分界线分开,分界线需要单独一行,如 --AaB03x--  
    //  
    //    分界线的下一行,是下一个字段  
    //  
    //    content-disposition: form-data; name="pic"; filename="boris.png"  
    //    Content-Type: image/png  
    //  
    //    ... contents of boris.png ...  
    //    --AaB03x--  
    //  
    //    这里声明了变量pic,也就是我们要传的文件,上传文件的时候需要在后边指定file name:filename="boris.png"  
    //    并且需要在下一行指定文件的格式:Content-Type: image/png  
    //  
    //  
    //    ... contents of boris.png ...  这里是boris.png的二进制内容,如 <89504e47 0d0a1a0a 0000000d 49484452 000000b4 000000b4 08020000 00b2af91 65000020 00494441 5478012c dd79b724 6b7616f6 8c888c88 8c9c8733 55ddb1d5 6a0db486 06218401 ......  
    //  
    //    在http post请求的结尾,需要有一个分界线,但是是前后都有--的:--AaB03x--  
    //  
    //    以上的这些格式,是http的规范,每个空行,空格都是必须的。  
    // 1. 创建url  
    NSURL *url = [NSURL URLWithString:urlString];  
    // 2. 创建请求  
    NSMutableURLRequest *mulRequest = [NSMutableURLRequest requestWithURL:url];  
    
    // 2.5 规定请求方式为POST请求  
    [mulRequest setHTTPMethod:@"POST"];  
    
    // 要上传的数据 其实post请求的第一种方式跟get请求很相似,只是将请求的参数放入了请求体中,而get是放在url中  
    NSString *postStr = @"username=Charles&password=yaoxin&message=helloworld";  
    // 转化为二进制数据  
    NSData *postData = [postStr dataUsingEncoding:NSUTF8StringEncoding];  
    // 3. 设置请求  
    // 设置请求体  
    [mulRequest setHTTPBody:postData];  
    
    // 设置请求头,01 - 设置请求数据的长度  
    [mulRequest setValue:[NSString stringWithFormat:@"%lu",postData.length] forHTTPHeaderField:@"Content-Length"];  
    // 02 - 设置请求数据的类型  
    [mulRequest addValue:@"application/x-www/form-urlencoded" forHTTPHeaderField:@"Content-Type"];  
    
    
    // 4.创建连接,发送请求  
    _urlConnection  = [[NSURLConnection alloc] initWithRequest:mulRequest delegate:self];  
    
    屏幕快照 2019-04-22 上午11.17.19.png
    #import "ViewController.h"
    
     //分隔符
    #define YFBoundary @"AnHuiWuHuYungFan"
    //换行
    #define YFEnter [@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]
    //NSString转NSData
    #define YFEncode(string) [string dataUsingEncoding:NSUTF8StringEncoding]
    
    @interface ViewController ()<NSURLSessionTaskDelegate>
    
    @property (weak, nonatomic) IBOutlet UIProgressView *uploadProgress;
    @property (weak, nonatomic) IBOutlet UILabel *uploadInfo;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        //1、确定URL
        NSURL *url = [NSURL URLWithString:@"http://192.168.0.5/AppTestAPI/UploadServlet"];    
        //2、确定请求
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];  
        //3、设置请求头
        NSString *head = [NSString stringWithFormat:@"multipart/form-data;boundary=--%@", YFBoundary];
        [request setValue:head forHTTPHeaderField:@"Content-Type"];
        //4、设置请求方式,上传时必须是Post请求
        request.HTTPMethod = @"POST";
        //5、创建NSURLSession
        NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
        //6、获取上传的数据
        NSData *uploadData = [self getData];
        //7、创建上传任务 上传的数据来自getData方法
        NSURLSessionUploadTask *task = [session uploadTaskWithRequest:request fromData:uploadData completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
            
           //上传成功以后改变UILabel文本为服务器返回的数据
           self.uploadInfo.text =[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
        
        }];
        //8、执行上传任务
        [task resume];
        
    }
    
    
    /**
     *  设置请求体
     *
     *  @return 请求体内容
     */
    -(NSData *)getData
    {
    
        NSMutableData *data = [NSMutableData data];
        
        //1、开始标记
        //--
        [data appendData:YFEncode(@"--")];
        //boundary
        [data appendData:YFEncode(YFBoundary)];
        //换行符
        [data appendData:YFEnter];
        //文件参数名 Content-Disposition: form-data; name="myfile"; filename="wall.jpg"
        [data appendData:YFEncode(@"Content-Disposition:form-data; name=\"myfile\"; filename=\"wall.jpg\"")];
        //换行符
        [data appendData:YFEnter];
        //Content-Type 上传文件的类型 MIME
        [data appendData:YFEncode(@"Content-Type:image/jpeg")];
        //换行符
        [data appendData:YFEnter];
        //换行符
        [data appendData:YFEnter];
        //2、上传的文件数据
        
        //图片数据  并且转换为Data
        UIImage *image = [UIImage imageNamed:@"wall.jpg"];
        NSData *imagedata = UIImageJPEGRepresentation(image, 1.0);
        [data appendData:imagedata];
        //换行符
        [data appendData:YFEnter];
     
        //3、结束标记
        //--
        [data appendData:YFEncode(@"--")];
        //boundary
        [data appendData:YFEncode(YFBoundary)];
        //--
        [data appendData:YFEncode(@"--")];
        //换行符
        [data appendData:YFEnter];
        
        return data;
        
    }
    
    #pragma mark - 代理方法 只要给服务器上传数据就会调用 可以计算出上传进度
    - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend
    {
    
        //设置进度条
        self.uploadProgress.progress = 1.0 * totalBytesSent / totalBytesExpectedToSend;
    }
    
    @end
    

    相关文章

      网友评论

          本文标题:(转)POST请求的两种格式

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