在ios中使用查询string创buildNSURLRequest

我在ios中创build了一个用户查询表单。 我使用PHP作为服务器端。 我在IOS中构造了如下波形的查询string

http://www.mydomain.in/androidmail_enquiry.php?name=Vinoth Kumar&phone=04259280244&email=vinoth@ldomain.com&address=Coimbatore&comments=Sample Enquiry&mobile=xxxxxxxx 

码:

 -(void)sendEnquiryDetails { cmttextview.text = @"Sample Enquiry"; NSString *siteurl = @"http://www.mydomain.in/androidmail_enquiry.php?"; NSString *name = txtName.text; NSString *phone = txtPhone.text; NSString *email = txtEmail.text; NSString *address = txtAddress.text; NSString *comments = cmttextview.text; NSString *mobile = txtMobile.text; NSString *enquiryurl = [NSString stringWithFormat:@"%@name=%@&phone=%@&email=%@&address=%@&comments=%@&mobile=%@",siteurl,name,phone,email,address,comments,mobile]; NSLog(enquiryurl); NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:enquiryurl]]; NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self]; } - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { //NSLog(@"didReceiveResponse"); [self.responseData setLength:0]; } -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { [self.responseData appendData:data]; } -(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { NSLog(@"%@",[NSString stringWithFormat :@"didfailwitherror: %@", [error description]]); } -(void)connectionDidFinishLoading: (NSURLConnection *)connection{ NSLog(@"Success Code:%@",self.responseData); } 

但是,当我通过使用NSURLRequest获取错误,如didFailWithError方法中的无效url(URL形成错误)提交此。

确保你已经添加了stringByAddingPercentEscapesUsingEncoding ,因为在你的url中有名字空间,所以在浏览器中用%20代替,你必须在代码中以编程方式添加,

尝试这个

 -(void)sendEnquiryDetails { cmttextview.text = @"Sample Enquiry"; NSString *siteurl = @"http://www.mydomain.in/androidmail_enquiry.php?"; NSString *name = txtName.text; NSString *phone = txtPhone.text; NSString *email = txtEmail.text; NSString *address = txtAddress.text; NSString *comments = cmttextview.text; NSString *mobile = txtMobile.text; NSString *enquiryurl = [NSString stringWithFormat:@"%@name=%@&phone=%@&email=%@&address=%@&comments=%@&mobile=%@",siteurl,name,phone,email,address,comments,mobile]; NSLog(enquiryurl); NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:[enquiryurl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]]; NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self]; } 

你必须转义保留字符。 如果没有别的,你必须用+ (或%20 )replace那些空格。

不幸的是,标准的stringByAddingPercentEscapesUsingEncoding不能胜任这个工作,因为它留下了一些未转义的字符。 你的样本不包括其中的任何一个,但是如果这个人的名字是作为“Bill&Melinda Gates”或“Bill + Melinda Gates”input的, stringByAddingPercentEscapesUsingEncoding就不能正确处理。 你真的应该使用CFURLCreateStringByAddingPercentEscapes来百分比转义值,例如使用这个类别:

 @implementation NSString (URLEncode) - (NSString *)stringForHTTPRequest { NSString *result = CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)self, (CFStringRef)@" ", (CFStringRef)@":/?@!$&'()*+,;=", kCFStringEncodingUTF8)); return [result stringByReplacingOccurrencesOfString:@" " withString:@"+"]; } @end 

这适当地转义所有保留的字符,但用+字符replace空格(如果你的请求types是application/x-www-form-urlencoded ,你应该这样做)。

或者,也可以用%20replace空格字符,如下所示:

 - (NSString *)stringForHTTPRequest { return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)self, NULL, (CFStringRef)@":/?@!$&'()*+,;=", kCFStringEncodingUTF8)); } 

有了这个,你可以修改构buildURLstring的那一行代码:

 NSString *enquiryurl = [NSString stringWithFormat:@"%@name=%@&phone=%@&email=%@&address=%@&comments=%@&mobile=%@", siteurl, [name stringForHTTPRequest], [phone stringForHTTPRequest], [email stringForHTTPRequest], [address stringForHTTPRequest], [comments stringForHTTPRequest], [mobile stringForHTTPRequest]]; 

根据文档,如果NSURL对象用string初始化,则string必须符合RFC 2396 (请参阅官方Apple文档URLWithString )。

但是最新的RFC是RFC 3986 ,它废弃了RFC 2396。

警告:

尽pipe如此,cocoa和核心基金会都没有一个函数能够返回符合RFC 2396或RFC 3986的正确编码的URLstring。

URL的不同组件具有不同百分比的编码要求。

编辑:

为了在URL的非结构化查询组件中传输结构化参数,可以将等于application / x-www-form-urlencoded编码algorithm的编码scheme应用于查询组件。

编码名称并且符合该编码的帮助函数可以被实现为:

 static NSString* urlformdata_encode(NSString* s) { CFStringRef charactersToLeaveUnescaped = CFSTR(" "); CFStringRef legalURLCharactersToBeEscaped = CFSTR("!$&'()+,/:;=?@~"); NSString *result = CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes( kCFAllocatorDefault, (__bridge CFStringRef)s, charactersToLeaveUnescaped, legalURLCharactersToBeEscaped, kCFStringEncodingUTF8)); return [result stringByReplacingOccurrencesOfString:@" " withString:@"+"]; } 

(注意:这个代码依赖于CFURLCreateStringByAddingPercentEscapes的当前实现,尤其是它的默认转义,如果这些改变,代码可能不能正确实现algorithm。

根据RFC 3986,URL的query组件被视为仅包含ASCII字符的非结构化百分比编码字节stream。

原来,“application / x-www-form-urlencoded”编码scheme已被定义用于将表单数据从浏览器传输到服务器,成为一个主体的有效载荷。 也就是说,上下文与URL完全不同。 尽pipe如此,即使这种编码scheme没有在RFC 3986中定义,它最终与URL编码scheme兼容。

注意事项

“application / x-www-form-urlencoded”编码scheme可能会为符合RFC 3986的“未保留”字符集(即波浪号~字符)的字符产生百分号转义。 “未保留”字符集中的字符不需要转义。 更严格地说,由于URI比较实现的含义,RFC 3986提出了这个build议:

为了一致性,在ALPHA(%41-%5A和%61-%7A),DIGIT(%30-%39),连字符(%2D),周期(%2E),下划线%5F)或者代字号(%7E)不应该由URI生成者创build“

为了不在查询参数中legalURLCharactersToBeEscaped波浪号~ ,可以从要设置的合法URL字符集中删除波浪号legalURLCharactersToBeEscaped

 CFStringRef legalURLCharactersToBeEscaped = CFSTR("!$&'()+,/:;=?@"); 

即使不是严格的“application / x-www-form-urlencoded encoding”algorithm,转义符不应该引起问题。

这个问题与其他推荐algorithm的区别在于:

由于“应用程序/ x-www-form-urlencoded”解码algorithm将任何百分比解码字符序列解码为其对应的Unicode代码单元,编码期间在CFURLCreateStringByAddingPercentEscapes中指定的CFURLCreateStringByAddingPercentEscapes集合中的legalURLCharactersToBeEscaped 可能最终产生相等的string。

(编辑:删除了编码URL组件的帮助函数,当查询string应该通过application / x-www-form-urlencoded进行编码时,这些函数是不相关的)