2013-07-03 45 views
5

我使用下面的代碼,IOS不編碼加號(+)登錄x-www-form-urlencoded POST請求?

NSString *jsonD = [NSString stringWithFormat:@"rawJson=%@",[fbUserInfo jsonUTF8String]]; 
NSData *myRequestData = [jsonD dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; 

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url 
                  cachePolicy:policy timeoutInterval:20.0]; 

[ request setHTTPMethod: @"POST" ]; 
[request setValue:[NSString stringWithFormat:@"%d", [myRequestData length]] forHTTPHeaderField:@"Content-Length"]; 
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; 
[ request setHTTPBody: myRequestData ]; 

在這段代碼中我有日期2013-06-29T18:33:17+0000。問題是我的服務器接收日期爲2013-06-29T18:33:17 0000。看到空間。我不知道爲什麼會發生這種情況。

回答

4

只是因爲你指定的編碼頭並不意味着NSURLRequest實際上執行表示編碼。

CFURLCreateStringByAddingPercentEscapes函數可以爲您的字符串進行URL編碼。

如果你不關心編碼,只想發送簡單的字符串,我建議你完全跳過編碼,並使用「text/plain」內容類型。

另一種選擇是使用JSON而不是表單編碼(「application/json」)。 JSON在服務器端和客戶端都更容易使用。可可已經內建了對JSON的支持。

編輯:現在我再次讀取您的代碼,我看到您的變量的名稱表明數據已經是JSON。如果是這樣,解決方案是使用"application/json"內容類型,並確保服務器正確理解和解碼。

+0

我需要x-www-form-urlencoded編碼嗎?這是一樣的嗎?我會試着讓你知道 – user960567

+0

不一定,如果你需要對對象進行形式編碼(即數組,字典和其他東西),你也需要將它們編碼爲鍵值對。對於簡單的字符串來說,轉義應該足夠了。 – Krumelur

+0

這不是一個簡單的JSON。它來自第三方。我需要正確編碼爲x-www-form-urlencoded – user960567

1

如果您需要有' ' - >'+'替代,您需要自行完成。

請參閱:Objective-c iPhone percent encode a string?爲代碼做轉換。


更新

OK,根據您的意見,這裏是一些額外的信息。基於舊查詢字符串的處理,'+'字符變成' '個字符。

它被載入舊的JavaScript,CGI和PHP處理URL。

微軟甚至有一個buggy example展示它。

您可以通過始終將'+'轉換爲'%2B'' ''%20'來避免此問題。

+0

我向客戶發送plus。我需要在服務器上獲得+。我只需要這個 – user960567

+0

@ user960567我更新了我的帖子,並提供了一些有關爲什麼發生這種情況的信息。 –

1

AFNetworking庫解決它正是如此:

static NSString * AFPercentEscapedQueryStringPairMemberFromStringWithEncoding(NSString *string, NSStringEncoding encoding) { 
    static NSString * const kAFCharactersToBeEscaped = @":/?&=;[email protected]#$()~',*"; 
    static NSString * const kAFCharactersToLeaveUnescaped = @"[]."; 

    return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)string, (__bridge CFStringRef)kAFCharactersToLeaveUnescaped, (__bridge CFStringRef)kAFCharactersToBeEscaped, CFStringConvertNSStringEncodingToEncoding(encoding)); 
} 
+0

你願意詳細說明嗎? – FluffulousChimp

+0

是的,對不起,這很有意思。我的觀點是,第三方庫不是解決所有問題的辦法。這確實解決了(我猜)問題,但完全避免了這個問題。我沒有downvote,雖然它提供了一個解決問題的辦法:) –

+0

我同意;我只是將實現作爲其他人解決問題的一個例子,而不是主張使用該庫_inToto_。 – FluffulousChimp

1

由於@Krumelur建議,該CFURLCreateStringByAddingPercentEscapes功能可URL編碼的字符串爲您服務。 這裏是代碼。

static NSString * CTPercentEscapedQueryStringValueFromStringWithEncoding(NSString *string, NSStringEncoding encoding) { 
    return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)string, NULL, (__bridge CFStringRef)kCharactersToBeEscapedInQueryString, CFStringConvertNSStringEncodingToEncoding(encoding)); 
} 

和完整的解決方案 :從參數使用下面的代碼來獲得編碼的URL。

/** 
get parameterized url from url and query parameters. 
*/ 
+(NSString *)getParameterizedUrl:(NSString *)url withParameters:(NSDictionary *)queryDictionary 
{ 
    NSMutableArray *mutablePairs = [NSMutableArray array]; 
    for (NSString *key in queryDictionary) { 
     [mutablePairs addObject:[NSString stringWithFormat:@"%@=%@", CTPercentEscapedQueryStringKeyFromStringWithEncoding(key, NSUTF8StringEncoding), CTPercentEscapedQueryStringValueFromStringWithEncoding(queryDictionary[key], NSUTF8StringEncoding)]]; 
    } 

    return [[NSString alloc]initWithFormat:@"%@?%@",url,[mutablePairs componentsJoinedByString:@"&"]]; 
} 

static NSString * const kCharactersToBeEscapedInQueryString = @":/?&=;[email protected]#$()',*"; 

static NSString * CTPercentEscapedQueryStringKeyFromStringWithEncoding(NSString *string, NSStringEncoding encoding) { 
    static NSString * const kCharactersToLeaveUnescapedInQueryStringPairKey = @"[]."; 

    return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)string, (__bridge CFStringRef)kCharactersToLeaveUnescapedInQueryStringPairKey, (__bridge CFStringRef)kCharactersToBeEscapedInQueryString, CFStringConvertNSStringEncodingToEncoding(encoding)); 
} 

static NSString * CTPercentEscapedQueryStringValueFromStringWithEncoding(NSString *string, NSStringEncoding encoding) { 
    return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)string, NULL, (__bridge CFStringRef)kCharactersToBeEscapedInQueryString, CFStringConvertNSStringEncodingToEncoding(encoding)); 
} 

並在代碼中用作

NSString *url = [self getParameterizedUrl:@"http://www.example.com" withParameters:self.params]; 

注:PARAMS這裏是字典。