Ошибка типа содержимого AFNetworking версии 2
Я пытаюсь сделать приложение iphone, которое будет взаимодействовать с конкретным сервером JIRA. У меня есть следующий код для входа в систему:
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];
Но это дает мне следующую ошибку, связанную с Content-Type:
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",
Я не уверен, в чем проблема. Я нашел этот вопрос, который, как я думал, может быть аналогичной проблемой, но ответы говорят либо использовать класс AFJSONRequestOperation
(который я не может, потому что я использую AFNetworking версии 2, которая не имеет этого класса), или исправить ее на стороне сервера (что я также не могу по понятным причинам).
Что я могу исправить эту ошибку, если не могу исправить серверную часть, и я не могу использовать AFJSONRequestOperation
?
Ответы
Ответ 1
Если вы используете 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);
}];
Это создает запрос, устанавливая его Content-Type
в соответствии с настройкой requestSerializer
и кодируя JSON для вас. Одним из преимуществ AFNetworking является то, что вы можете выйти из сорняков при конструировании и настройке объектов NSURLRequest
вручную.
Кстати, ошибка "Ошибка запроса: неприемлемый тип контента: текст /html " означает, что независимо от того, что вы ожидали получить (например, JSON), вы получили ответ HTML. Это очень распространено: многие ошибки сервера (например, сервер, информирующий вас о том, что запрос был искажен и т.д.) Генерируют сообщения об ошибках HTML. Если вы хотите увидеть этот HTML-код в своем блоке failure
, просто запишите operation.responseString
.
Ответ 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"];
... который не работал. Престижность Робу за то, что он работает!
Ответ 3
У меня была такая же проблема в AFNetworking 2.0, и я решил, что должен установить тип AFHTTPRequestSerializer (в случае, если ваш запрос JSON), он должен быть таким.
AFHTTPSessionManager *myHTTPManager = ...
[myManager setRequestSerializer:[AFJSONRequestSerializer serializer]];
Вы должны установить как AFHTTPResponseSerializer
, так и AFHTTPRequestSerializer
Ответ 4
если вы используете класс по умолчанию 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;}
Ответ 5
Используйте эту строку кода.
operation.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];