我正在尝试通过数据库上的 HTTP Post 网络服务获取 CSV 文件,以便我可以解析它。我目前有这段代码
-(void)viewDidLoad{
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://192.x.x.x/xyz.php?cmd=select * from record and datetime>'%@ 00:00:00' and datetime<'%@ 23:59:59' order by id limit 15", startDate, endDate]]];
[request setHTTPMethod:@"POST"];
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if(conn)
{
NSLog(@"Connection Successful");
}
else
{
NSLog(@"Connection could not be made");
}}
////////////////////////////
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSLog(@"Did Receive Data method was called");
NSString *contentString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
csvParser = [[CHCSVParser alloc] initWithContentsOfCSVFile:contentString];
ParserDelegate *parserDelegate = [[ParserDelegate alloc] initParser];
[csvParser setDelegate: parserDelegate];
[csvParser parse];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"Error: %@", error);
}
这是我从调试日志中得到的
Command string: http://192.x.x.x/xyz.php?cmd=select * from record and datetime>'2003-10-30 08:00:00 +0000 00:00:00' and datetime<'2013-10-29 07:00:00 +0000 23:59:59' order by id limit 15
[615:c07] Connection Successful
[615:c07] Error: Error Domain=NSURLErrorDomain Code=-1000 "bad URL" UserInfo=0x7561fd0 {NSUnderlyingError=0x71eb1c0 "bad URL", NSLocalizedDescription=bad URL}
我得到这个错误的 URL。我可以通过网络浏览器访问 URL(浏览器可能会做一些事情)。有谁知道问题是什么以及如何解决?
谢谢
最佳答案
您需要对查询进行百分比编码:
您的查询包含一个参数(键/值):
key: @"cmd"
value: @"select * from record and datetime>'%@ 00:00:00' and datetime<'%@ 23:59:59' order by id limit 15"
键和值在组成参数字符串之前需要正确编码。 参数字符串将由编码的键、“=”和编码的值组成。
可以在此处找到对一个键或值进行编码的算法:application/x-www-form-urlencoded encoding algorithm .
另请参阅RFC 3986 .
为了对参数值或参数键进行编码,您可以使用此辅助函数,如以下答案所示:( Unable to create NSUrl from NSString always getting nil )
注意:
通常,POST 请求会将查询参数放入请求正文中。然而,该标准并没有明确禁止这样做。 POST 请求应该使用 URL 中的查询参数字符串。
话虽如此,可能更好的方法是将查询放入正文中:
您可以将正文的内容类型设置为“application/x-www-form-urlencoded”(在 header 中),然后使用相同的编码算法。
所以,如果您想尝试“application/x-www-form-urlencoded”:
- 将请求的
Content-Type
header 设置为“application/x-www-form-urlencoded” - 按上述方式序列化您的查询参数。
- 从生成的查询字符串中获取采用 UTF-8 编码的
NSData
对象,并使用此数据设置请求正文。
或者,您可以尝试其他内容类型,例如JSON。这是否可能取决于服务器的能力。老实说,内容类型“application/json”可能是首选方式。
所以,如果你想尝试“application/json”:
将请求的
Content-Type
设置为“application/json”将您的查询参数序列化为 JSON 对象,例如:
id jsonObject = @{@"cmd": @"select * from ... limit 15"};
利用
NSJSONSerialization
,您可以获取包含 UTF-8 格式的 JSON 的NSData
。使用此数据设置请求正文。
在这两种方法中,您还应该设置 Content-Length
header ,它是正文数据的长度(以字节为单位)。
辅助函数
以下辅助函数返回参数的编码名称字符串或编码值字符串:
static NSString* form_urlencode_rfc3986(NSString* s) {
CFStringRef charactersToLeaveUnescaped = CFSTR(" ");
//CFStringRef legalURLCharactersToBeEscaped = CFSTR("!$&'()+,/:;=?@~");
// Modified for urls (excluding '~'):
CFStringRef legalURLCharactersToBeEscaped = CFSTR("!$&'()+,/:;=?@");
NSString *result = CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(
kCFAllocatorDefault,
(__bridge CFStringRef)s,
charactersToLeaveUnescaped,
legalURLCharactersToBeEscaped,
kCFStringEncodingUTF8));
return [result stringByReplacingOccurrencesOfString:@" " withString:@"+"];
}
为了组成(编码的)参数字符串,请将“=”附加到编码名称,然后附加编码值。
为了组成(编码的)查询字符串,请通过用“&”分隔来连接所有编码的参数字符串。
关于ios - Objective-C - CHCSVParser 和 HTTP Post,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19665673/