4

我試圖做一個iPhone應用程序,將與特定的JIRA服務器進行交互。我有下面的代碼登錄:AFNetworking版本2內容類型錯誤

NSURL *url = [[NSURL alloc] initWithString:@"https://mycompany.atlassian.net/rest/auth/latest/session/"]; 
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; 
[request setHTTPMethod:@"POST"]; 
NSString *postString = [NSString stringWithFormat:@"{\"username\":\"%@\",\"password\":\"%@\"}", username, password]; 
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]]; 
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request]; 
[request setValue:@"application/json" forHTTPHeaderField:@"Accept" ]; 
operation.responseSerializer = [AFJSONResponseSerializer serializer]; 
[operation setCompletionBlockWithSuccess: 
    ^(AFHTTPRequestOperation *operation, id responseObject) { 
     NSLog(@"JSON: %@", responseObject); 
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
    NSLog(@"ERROR: %@", error); 

    } 
]; 
[operation start]; 

但它給我具有內容類型做了以下錯誤:

ERROR: Error Domain=AFNetworkingErrorDomain Code=-1011 
"Request failed: unsupported media type (415)" 
UserInfo=0x8cd6540 
{ 
    NSErrorFailingURLKey=https://mycompany.atlassian.net/rest/auth/latest/session/, 
    NSLocalizedDescription=Request failed: unsupported media type (415), 
    NSUnderlyingError=0x8c72e70 
    "Request failed: unacceptable content-type: text/html", 

我不知道是什麼問題。我發現this question,我認爲這可能是一個類似的問題,但答案說要麼使用AFJSONRequestOperation類(我不能因爲我使用AFNetworking版本2,它沒有那個類),或者修復它在服務器端(我也不能明顯的原因)。

當我無法修復服務器端,我無法使用AFJSONRequestOperation時,我該如何解決此錯誤?

+0

很高興您解決了您的問題。順便說一句,用'stringWithFormat'構建JSON是不可取的(如果密碼中包含某些字符,則會失敗)。最好使用NSDictionary * postDictionary = @ {@「username」:username,@「password」:password};'然後使用NSData * postBody = [NSJSONSerialization dataWithJSONObject:postDictionary options:0 error:&error];'創建'setHTTPBody'的'NSData'。或者在AF 2.0中使用'POST'和'AFJSONRequestSerializer'(在AF 1.x中使用'AFHTTPClient'和'AFJSONParameterEncoding'的parameterEncoding'),並且它會將字典轉換爲JSON。 – Rob

回答

14

如果使用AFNetworking 2.0,則可以使用POST方法,該方法簡化了這個位:

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; 
manager.requestSerializer = [AFJSONRequestSerializer serializer]; 
NSDictionary *parameters = @{@"username":username, @"password":password}; 
[manager POST:@"https://mycompany.atlassian.net/rest/auth/latest/session/" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) { 
    NSLog(@"JSON: %@", responseObject); 
} failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
    NSLog(@"Error: %@", error); 
}]; 

這確實請求的創建,根據requestSerializer設置的設置其Content-Type,並編碼JSON爲你。 AFNetworking的優勢之一是您可以擺脫手動構建和配置NSURLRequest對象的雜草。


順便說一句,「請求失敗:無法接受的內容類型:text/html的」錯誤意味着無論你期待能夠收到(例如JSON)是什麼,你收到HTML響應。這很常見:許多服務器錯誤(例如服務器通知您請求格式錯誤等)會生成HTML錯誤消息。如果您想在您的failure區塊中看到該HTML,只需登錄operation.responseString即可。

+0

它爲我工作。謝謝@Rob – shripad20

+0

你救了我的一天。謝謝。 – chancyWu

2

原來的問題是,這一條線:

[request setValue:@"application/json" forHTTPHeaderField:@"Accept" ]; 

應該

[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type" ]; 

錯誤,現在解決了。 (編輯:我應該有兩個,看CouchDeveloper的評論)

編輯
Rob的解決方案是更好的,所以我用它去。我實際上已經嘗試過類似的解決方案,他表示什麼,但他在那裏的線,

manager.requestSerializer = [AFJSONRequestSerializer serializer]; 

我行:

[manager.requestSerializer 
    setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; 

...沒有工作。榮譽給羅布得到它的工作!

+1

您可能同時需要:在標題爲「接受」的情況下,您可以指定在有響應時您想要接收的媒體類型。使用「Content-Type」標題指定您要發送的媒體類型。 「Content-Type」頭文件應該(確實應該)在你的請求中指定。 – CouchDeveloper

+0

@CouchDeveloper謝謝,這有助於我更好地理解這一點。 –

1

我在AFNetworking 2.0中有同樣的問題,解決方案是我必須確保我設置AFHTTPRequestSerializer類型(如果您的請求是JSON)它應該是這樣的。

AFHTTPSessionManager *myHTTPManager = ... 
[myManager setRequestSerializer:[AFJSONRequestSerializer serializer]]; 

必須設置兩個AFHTTPResponseSerializerAFHTTPRequestSerializer

0

如果您正在使用默認寫入類AFAppDotNetAPIClient,你面對這個錯誤。必須加responseSerializer。看看你的共享方法應該看起來像 -

+ (instancetype)sharedClient { 

static AFAppDotNetAPIClient *_sharedClient = nil; 
static dispatch_once_t onceToken; 

dispatch_once(&onceToken, ^{ 
    _sharedClient = [[AFAppDotNetAPIClient alloc] initWithBaseURL:[NSURL URLWithString:AFAppDotNetAPIBaseURLString]]; 
    _sharedClient.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone]; 
    _sharedClient.responseSerializer = [AFHTTPResponseSerializer serializer]; 
}); 
return _sharedClient;} 
0

使用此行代碼。

operation.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"]; 
相關問題