iOS端向后台(Python-django)POST多块数据(multipart/form)
2014-03-06 18:00
543 查看
前端iOS向后端Django传输多模块数据
HTTP POST请求,发送multipart/form-data
为了能够理解在iOS端对post数据所做的包装,可以先阅读这样一篇文章:HTTP请求基本介绍
阅读完上面这篇文章,就可以开始进行编写
// // EZHttpRequest.m // // Created by apple on 14-3-6. // Copyright (c) 2014年 apple. All rights reserved. // #import "EZHttpRequest.h" #define boundary @"---------------------------14737809831466499882746641449" #define file_key @"docfile" @implementation EZHttpRequest +(NSData *)post:(NSArray *)content toURL:(NSURL *)post_url{ /*---------------------form of content data--------------------- 1,Http header filed Content-Type:multipart/form-data; boundary=@"" Content-Length: 2,content: (1){boundary} (2)Content-Disposition:form-data;name=@"" *(3)If data is not string,add:Content-Type: (4)data 3,every line should end with '\r\n' ---------------------form of content data---------------------*/ //create url request NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; [request setURL:post_url]; [request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData]; [request setHTTPShouldHandleCookies:NO]; [request setTimeoutInterval:30]; [request setHTTPMethod:@"POST"]; //set HTTP header NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary]; [request setValue:contentType forHTTPHeaderField: @"Content-Type"]; //set post data NSData *post_body = [self pack:content]; [request setHTTPBody:post_body]; //set content length to HTTP header [request setValue:[NSString stringWithFormat:@"%ld",[post_body length]] forHTTPHeaderField:@"Content-Length"]; //post request NSError *error; NSHTTPURLResponse *response = nil; NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; return result; } +(NSData *)pack:(NSArray *)content{ /*----------------form of content array---------------- ( { parameter_name: @"", parameter_data: NSData, parameter_type: NSNumber:(text:0,file:1) }dictionary )array ----------------form of content array----------------*/ NSMutableData *postData = [NSMutableData data]; for(int i=0;i<content.count;i++){ NSDictionary *dic = [content objectAtIndex:i]; //boundary [postData appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; //Content dispostion NSNumber *type = [dic objectForKey:@"parameter_type"]; if([type integerValue] == 0){//text data //parameter name NSString *parameter_name = [dic objectForKey:@"parameter_name"]; NSString *name_string = [NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n",parameter_name]; [postData appendData:[name_string dataUsingEncoding:NSUTF8StringEncoding]]; }else{//file data NSString *parameter_name = [dic objectForKey:@"parameter_name"]; [postData appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", file_key,parameter_name] dataUsingEncoding:NSUTF8StringEncoding]]; [postData appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; } //parameter data NSData *parameter_data = [dic objectForKey:@"parameter_data"]; [postData appendData:parameter_data]; //end [postData appendData:[[NSString stringWithFormat:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; } [postData appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; return postData; } @end
为了方便以后的使用,将它写进了一个类中,需要时可以调用方法:
NSData *result = [EZHttpRequest post:array toURL:[NSURL URLWithString:@"http://url/"]];这里的array是一个以字典为元素的数组,具体的array创建可以参见:
NSDictionary *username = [[NSDictionary alloc]initWithObjectsAndKeys: @"parameter1",@"parameter_name", [@"what's my name?" dataUsingEncoding:NSUTF8StringEncoding],@"parameter_data", [NSNumber numberWithInteger:0],@"parameter_type", nil]; NSDictionary *video = [[NSDictionary alloc]initWithObjectsAndKeys: @"video.MOV",@"parameter_name", videoData,@"parameter_data", [NSNumber numberWithInteger:1],@"parameter_type", nil]; NSArray *array = [[NSArray alloc]initWithObjects:username,video, nil];
其中parameter_type是为了方便控制后期post data的包装,可能很不成熟,日后有机会了再进行提升
如此一来,在后端可以通过键值"parameter1"得到这个字符数据,同样可以通过键值"docfile"得到上传的文件(这个docfile是在包装post data过程中,给文件数据模块定义的键值)
下面是Django端获取这些post的简单示例
Django project named 'video'
One app in project named 'upload'
Model in 'upload':
from django.db import models class Video(models.Model): v_video = models.FileField(upload_to='documents/%Y/%m/%d')
Views in 'upload':
from django.shortcuts import render from models import Video from upload.forms import DocumentForm from django.http import HttpResponse from django.views.decorators.csrf import csrf_exempt @csrf_exempt def uploadMyVideo(request): form = DocumentForm(request.POST,request.FILES) if form.is_valid(): new = Video(v_video = request.FILES['docfile']) new.save() string = request.POST['username'] return HttpResponse(string) return HttpResponse('not valid')
其中upload.forms是upload目录下的一个自创的forms.py文件,这个具体是参考Stackoverflow中一位同志的回答,具体这样写的理由有待发掘,下面是forms.py中的内容
# -*- coding: utf-8 -*- from django import forms class DocumentForm(forms.Form): docfile = forms.FileField( label='Select a file' )
以上便是iOS向Django POST多块数据的例子,编码不太成熟,有待多多练习。
相关文章推荐
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- HTTP Header 属性列表
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- 深入HTTP head的使用详解
- ASP 中使用 HTTP 协议发送参数详解
- http www安全必备知识
- sql2005 附加数据库出错(错误号:5123)解决方法
- asp HTTP 500错误 常见问题分析
- POST与GET方法的区别简要分析
- http代理相关知识分析
- asp #include file 与 #include virtual 的区别小结第1/2页
- 分享下GET和POST的真正区别
- php错误提示failed to open stream: HTTP request failed!的完美解决方法
- ajax 的post方法实例(带循环)
- PHP file_exists问题杂谈
- ASP.NET的HtmlForm控件学习及Post与Get的区别概述
- asp教程中get post提交表单有5点区别
- asp.net 从POST的数据流中提取参数和文件