通过多部分HTTP请求上传ios文本
我正在尝试在iOS中使用通过多部分HTTP请求上传ios文本,ios,http-post,nsurlconnection,Ios,Http Post,Nsurlconnection,我正在尝试在iOS中使用多部分表单编码上传文本 我所做的: NSMutableDictionary *params = [NSMutableDictionary new]; [params setObject:@"XXXXX" forKey:@"apikey"]; [params setObject:@"DataAPI" forKey:@"scope"]; [params setObject:@"push" forKey:@"action"]; [para
多部分表单编码上传文本
我所做的:
NSMutableDictionary *params = [NSMutableDictionary new];
[params setObject:@"XXXXX" forKey:@"apikey"];
[params setObject:@"DataAPI" forKey:@"scope"];
[params setObject:@"push" forKey:@"action"];
[params setObject:docName forKey:@"documentName"];
[params setObject:content forKey:@"content"];
[params setObject:authToken forKey:@"authtoken"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
[request setHTTPShouldHandleCookies:NO];
[request setTimeoutInterval:30];
[request setHTTPMethod:@"POST"];
// set Content-Type in HTTP header
NSString *boundary = @"V2ymHFg03ehbqgZCaKO6jy";
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
[request setValue:contentType forHTTPHeaderField: @"Content-Type"];
NSMutableData *body = [NSMutableData data];
// add params (all params are strings)
for (NSString *param in params) {
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", param] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"%@\r\n", [params objectForKey:param]] dataUsingEncoding:NSUTF8StringEncoding]];
}
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
// setting the body of the post to the reqeust
[request setHTTPBody:body];
NSString *myString = [[NSString alloc] initWithData:body encoding:NSUTF8StringEncoding];
NSLog(@"%@",myString);
// set the content-length
NSString *postLength = [NSString stringWithFormat:@"%d", [body length]];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
// set URL
[request setURL:url];
NSURLResponse *response;
NSData *POSTReply = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
NSString *theReply = [[NSString alloc] initWithBytes:[POSTReply bytes] length:[POSTReply length] encoding: NSASCIIStringEncoding];
NSLog(@"Reply: %@", theReply);
我已尝试通过中提供的信息
问题:
NSMutableDictionary *params = [NSMutableDictionary new];
[params setObject:@"XXXXX" forKey:@"apikey"];
[params setObject:@"DataAPI" forKey:@"scope"];
[params setObject:@"push" forKey:@"action"];
[params setObject:docName forKey:@"documentName"];
[params setObject:content forKey:@"content"];
[params setObject:authToken forKey:@"authtoken"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
[request setHTTPShouldHandleCookies:NO];
[request setTimeoutInterval:30];
[request setHTTPMethod:@"POST"];
// set Content-Type in HTTP header
NSString *boundary = @"V2ymHFg03ehbqgZCaKO6jy";
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
[request setValue:contentType forHTTPHeaderField: @"Content-Type"];
NSMutableData *body = [NSMutableData data];
// add params (all params are strings)
for (NSString *param in params) {
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", param] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"%@\r\n", [params objectForKey:param]] dataUsingEncoding:NSUTF8StringEncoding]];
}
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
// setting the body of the post to the reqeust
[request setHTTPBody:body];
NSString *myString = [[NSString alloc] initWithData:body encoding:NSUTF8StringEncoding];
NSLog(@"%@",myString);
// set the content-length
NSString *postLength = [NSString stringWithFormat:@"%d", [body length]];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
// set URL
[request setURL:url];
NSURLResponse *response;
NSData *POSTReply = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
NSString *theReply = [[NSString alloc] initWithBytes:[POSTReply bytes] length:[POSTReply length] encoding: NSASCIIStringEncoding];
NSLog(@"Reply: %@", theReply);
我把日志放在服务器端,下面是我从IOS应用程序收到的信息
键
名称没有问题。但是,我将值作为null
"443" "POST" "/api/private/json/" "content=null&scope=null&action=null&documentname=null&apikey=null"
我的代码:
NSMutableDictionary *params = [NSMutableDictionary new];
[params setObject:@"XXXXX" forKey:@"apikey"];
[params setObject:@"DataAPI" forKey:@"scope"];
[params setObject:@"push" forKey:@"action"];
[params setObject:docName forKey:@"documentName"];
[params setObject:content forKey:@"content"];
[params setObject:authToken forKey:@"authtoken"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
[request setHTTPShouldHandleCookies:NO];
[request setTimeoutInterval:30];
[request setHTTPMethod:@"POST"];
// set Content-Type in HTTP header
NSString *boundary = @"V2ymHFg03ehbqgZCaKO6jy";
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
[request setValue:contentType forHTTPHeaderField: @"Content-Type"];
NSMutableData *body = [NSMutableData data];
// add params (all params are strings)
for (NSString *param in params) {
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", param] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"%@\r\n", [params objectForKey:param]] dataUsingEncoding:NSUTF8StringEncoding]];
}
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
// setting the body of the post to the reqeust
[request setHTTPBody:body];
NSString *myString = [[NSString alloc] initWithData:body encoding:NSUTF8StringEncoding];
NSLog(@"%@",myString);
// set the content-length
NSString *postLength = [NSString stringWithFormat:@"%d", [body length]];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
// set URL
[request setURL:url];
NSURLResponse *response;
NSData *POSTReply = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
NSString *theReply = [[NSString alloc] initWithBytes:[POSTReply bytes] length:[POSTReply length] encoding: NSASCIIStringEncoding];
NSLog(@"Reply: %@", theReply);
我无法理解这个问题,无论是从服务器端还是从我的代码
谢谢分享您的答案。您没有附加终止边界
这:
应该是这样的:
[body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
for (NSString *param in params) {
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Type: text/plain\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", param] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"%@\r\n", [params objectForKey:param]] dataUsingEncoding:NSUTF8StringEncoding]];
}
[body appendData:[[NSString stringWithFormat:@"\r\n\r\n--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
编辑:
实际上,你错过了更多的东西。您没有设置数据的内容类型,并且缺少一些新行
您的循环应该如下所示:
[body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
for (NSString *param in params) {
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Type: text/plain\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", param] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"%@\r\n", [params objectForKey:param]] dataUsingEncoding:NSUTF8StringEncoding]];
}
[body appendData:[[NSString stringWithFormat:@"\r\n\r\n--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
EDIT2:
下面是一个服务器端代码示例,它正确地处理了相同的请求:
#!/usr/bin/env python
import web
urls = ("/", "Index")
app = web.application(urls, globals())
class Index(object):
def POST(self):
x = web.input()
print x
print x['apikey']
print x['scope']
return 'success'
if __name__ == "__main__":
app.run()
输出:
<Storage {'scope': u'asd', 'apikey': u'123\r\n'}>
123
asd
127.0.0.1:60044 - - [02/Dec/2013 15:02:55] "HTTP/1.1 POST /" - 200 OK
//这里是编码方法
- (NSData*)编码字典:(NSDictionary*)字典{
NSMUTABLEARRY*部件=[[NSMUTABLEARRY alloc]init];
for(NSString*字典中的键){
NSString*encodedValue=[[dictionary objectForKey:key]stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString*encodedKey=[key stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString*part=[NSString stringWithFormat:@“%@=%@”,encodedKey,encodedValue];
[零件添加对象:零件];
}
NSString*encodedDictionary=[parts Components由字符串连接:@“&”];
返回[encodedDictionary dataUsingEncoding:NSUTF8StringEncoding];
}
//也许这对你完全有帮助
这应该可以解决:
而不是:
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
写
(终止CRLF是可选的)
请注意,如果您这样写:
for (NSString *param in params) {
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Type: text/plain\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", param] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"%@\r\n", [params objectForKey:param]] dataUsingEncoding:NSUTF8StringEncoding]];
}
[body appendData:[[NSString stringWithFormat:@"\r\n\r\n--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
边界分隔符之前的所有内容,例如\r\n--
在概念上属于数据,例如属于参数值
同样,“破折号边界”(--
)前面的CRLF
属于分隔符
从概念上讲,第一个分隔符也必须以CRLF开头:
`CRLF--<boundary>`
前导码
可以是空的,也可以包含任意数量的CRLF
主体部分
,由MIME头和部分主体数据组成,紧跟在边界之后,但严格来说不是立即:
<preamble-bytes>CRLF--xyz<transport-padding>CRLF<body-part>
^~~~~~~~~ delimiter ^~~~~~~~~~~ MIME headers and data
然后紧接着是主体部分
(从标题开始,然后是数据):
这四条线可用于每个参数的循环中
可以按如下方式添加终止分隔符:
[body appendData:[[NSString stringWithFormat:@"\r\n--%@--", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
终止CRLF是可选的。最后一个CRLF之后的任何字节都属于尾声
,服务器将忽略这些字节
参见:RCF 2046。我做了更改。但响应相同。在为数据添加内容类型后,结果相同。请参阅我的第二次编辑。刚刚尝试了一个快速python脚本和一个控制台应用程序。看起来问题可能出在服务器端。
<preamble-bytes>CRLF--xyz<transport-padding>CRLF<body-part>
^~~~~~~~~ delimiter ^~~~~~~~~~~ MIME headers and data
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Type: text/plain\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"%@", (self.parameters)[key]] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"\r\n--%@--", boundary] dataUsingEncoding:NSUTF8StringEncoding]];