Falha na solicitação: tipo de conteúdo inaceitável: text / html usando o AFNetworking 2.0

205

Estou testando a nova versão 2.0 do AFNetworking e estou recebendo o erro acima. Alguma idéia de por que isso está acontecendo? Aqui está o meu código:

    NSURL *URL = [NSURL URLWithString:kJSONlink];
    NSURLRequest *request = [NSURLRequest requestWithURL:URL];
    AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    op.responseSerializer = [AFJSONResponseSerializer serializer];
    [op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@"JSON: %@", responseObject);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@", error);
    }];
    [[NSOperationQueue mainQueue] addOperation:op];

Estou usando o Xcode 5.0.

Além disso, aqui está a mensagem de erro:

Error: Error Domain=AFNetworkingErrorDomain Code=-1016 "Request failed: unacceptable content-type: text/html" UserInfo=0xda2e670 {NSErrorFailingURLKey=kJSONlink, AFNetworkingOperationFailingURLResponseErrorKey=<NSHTTPURLResponse: 0xda35180> { URL: kJSONlink } { status code: 200, headers {
    Connection = "Keep-Alive";
    "Content-Encoding" = gzip;
    "Content-Length" = 2898;
    "Content-Type" = "text/html";
    Date = "Tue, 01 Oct 2013 10:59:45 GMT";
    "Keep-Alive" = "timeout=5, max=100";
    Server = Apache;
    Vary = "Accept-Encoding";
} }, NSLocalizedDescription=Request failed: unacceptable content-type: text/html}

Eu apenas escondi o JSON usando o kJSONlink. Isso deve retornar um JSON.

jaytrixz
fonte

Respostas:

361

Isso significa que seu servidor está enviando em "text/html"vez dos tipos já suportados. Minha solução foi adicionar "text/html"ao acceptableContentTypesconjunto em AFURLResponseSerializationsala de aula. Basta procurar por "AcceptContentTypes" e adicionar @"text/html"ao conjunto manualmente.

Obviamente, a solução ideal é alterar o tipo enviado do servidor, mas para isso você terá que conversar com a equipe do servidor.

Andrei Neag
fonte
142
Obrigado! Acabei de adicionar este código para que ele funcione:op.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];
jaytrixz
13
Para PHP, é tão fácil quanto adicionar isso à página: header ("Content-Type: application / json"); (a menos que isso não é uma resposta JSON, XML, em seguida, ou algo)
rckehoe
1
@rckehoe Obrigado por este - muito preferido para alterar o cabeçalho página do que acceptableContentTypes:)
Nick
43
Uma alternativa para comentário @jaytrixz é apenas para adicionar um novo tipo de conteúdo para os já existentes:op.responseSerializer.acceptableContentTypes = [op.responseSerializer.acceptableContentTypes setByAddingObject:@"text/html"];
mgarciaisaia
11
Código Swift:op.responseSerializer.acceptableContentTypes = NSSet(object: "text/html")
Husam
178

Definir meu RequestOperationManagerserializador de resposta para HTTPResponseSerializercorrigir o problema.

Objetivo-C

manager.responseSerializer = [AFHTTPResponseSerializer serializer];

Rápido

manager.responseSerializer = AFHTTPResponseSerializer()

Fazer essa alteração significa que não preciso adicionar acceptableContentTypesa cada solicitação que faço.

Danpe
fonte
2
Eu fiz isso e ele trava meu aplicativo. Revertendo volta a usarAFJSONResponseSerializer
jaytrixz
2
@jaytrixz Depende, se o seu servidor sempre responder com JSON, você deve configurá-lo responseSerializercomo AFJSONResponseSerializer.
21413 Danpe
2
Agora você receberá o responseObject como NSData e precisará analisar o JSON no bloco de sucesso.
Cameron Lowell Palmer
1
Porque eu estou usando pods, então desta maneira é melhor.
yong ho
@ Danpe, Como converter a linha de código acima em Swift. Eu tentei com manager.responseSerializer = AFJSONResponseSerializer.serializer (), mas não adianta.
Ganesh Guturi
72

Eu levei a resposta / comentário de @jaytrixz um passo adiante e adicionei "text / html" ao conjunto de tipos existente. Dessa forma, quando eles corrigem no lado do servidor "application / json" ou "text / json", afirmo que funcionará perfeitamente.

  manager.responseSerializer.acceptableContentTypes = [manager.responseSerializer.acceptableContentTypes setByAddingObject:@"text/html"];
mharper
fonte
2
Acordado. A resposta aceita para essa pergunta tem uma enorme falha, pois cria uma bomba-relógio que explode quando o lado do servidor é corrigido para retornar o tipo de conteúdo correto.
Eric Goldberg
Isso parece certo em teoria, mas alguém realmente testou isso?
Minimi
32

No lado do servidor, adicionei:

header('Content-type: application/json');

no meu código .php e isso também resolveu o problema.

Chris Prince
fonte
3
if(!headers_sent() ) { header('Content-Type: application/json'); } É uma solução agradável
elliotrock
17

Eu resolvo esse problema de uma perspectiva diferente.

Eu acho que se o servidor envia dados JSON com Content-Type: text/htmlcabeçalho. Isso não significa que o servidor pretendeu enviar-lhe algum html, mas acidentalmente mudou para JSON. Isso significa que o servidor não se importa com o Content-Typecabeçalho. Portanto, se o funcionário do servidor não se importa com o lado do cliente, é melhor ignorar o Content-Typecabeçalho também. Para ignorar o Content-Typecabeçalho, faça check-inAFNetworking

manager.responseSerializer.acceptableContentTypes = nil;

Dessa maneira, o AFJSONResponseSerializer(o padrão) serializará os dados JSON sem fazer check- Content-Typein no cabeçalho da resposta.

dopcn
fonte
Exatamente correto. Ao ignorar o tipo de conteúdo, não recebo meu conteúdo como um código hexadecimal nem como uma resposta nula com falha. Isso funciona muito bem! Obrigado
Brandon
7

Uma maneira simples de permitir receber o tipo de conteúdo "texto / sem formatação":

manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/plain"];

Da mesma forma, se você deseja ativar o tipo de conteúdo "text / html":

manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];
da Rocha Pires
fonte
5

Tentei abaixo da linha de acordo com a resposta @Andrie, mas não funcionou,

op.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];

então, depois de caçar mais, trabalhei para que ele funcionasse com sucesso.

Aqui está o meu snip de código.

AFHTTPRequestOperationManager *operation = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:url];
    operation.responseSerializer = [AFJSONResponseSerializer serializer];

    AFJSONResponseSerializer *jsonResponseSerializer = [AFJSONResponseSerializer serializer];

    NSMutableSet *jsonAcceptableContentTypes = [NSMutableSet setWithSet:jsonResponseSerializer.acceptableContentTypes];
    [jsonAcceptableContentTypes addObject:@"text/plain"];
    jsonResponseSerializer.acceptableContentTypes = jsonAcceptableContentTypes;
    operation.responseSerializer = jsonResponseSerializer;

Espero que isso ajude alguém por aí.

abdômen
fonte
1
+1. Esta é definitivamente a solução. Como você deve definir o Tipo de conteúdo aceitável no serializador, se este for um serializador JSON (que normalmente está usando "application / json") e a operação. Caso contrário, você obterá configurações de erro apenas na operação.
loretoparisi
3

Esta é a única coisa que eu achei para trabalhar

-(void) testHTTPS {
    AFSecurityPolicy *securityPolicy = [[AFSecurityPolicy alloc] init];
    [securityPolicy setAllowInvalidCertificates:YES];

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    [manager setSecurityPolicy:securityPolicy];
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];

    [manager GET:[NSString stringWithFormat:@"%@", HOST] parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSString *string = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
        NSLog(@"%@", string);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@", error);
    }];
}
chrisallick
fonte
3

Se alguém estiver usando AFHTTPSessionManager, pode-se fazer assim para resolver o problema,

Eu subclassei AFHTTPSessionManageronde estou fazendo assim,

NSMutableSet *contentTypes = [[NSMutableSet alloc] initWithSet:self.responseSerializer.acceptableContentTypes];
[contentTypes addObject:@"text/html"];
self.responseSerializer.acceptableContentTypes = contentTypes;
Hemang
fonte
2

No meu caso, não tenho controle sobre a configuração do servidor, mas sei que ele espera "application / json" para "Content-Type". Eu fiz isso no lado do cliente iOS:

manager.requestSerializer = [AFJSONRequestSerializer serializer];

consulte o erro de tipo de conteúdo do AFNetworking versão 2

uudaddy
fonte
1

Basta adicionar esta linha:

operation.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];
Elangovan
fonte
0

Eu tive um problema semelhante ao trabalhar com o AFNetworking a partir de uma base de código Swift, então estou deixando isso aqui no caso remoto de que alguém é tão azarado quanto eu ter que trabalhar nessa configuração. Se você é, eu sinto seu amigo, fique forte!

A operação falhou devido a "tipo de conteúdo inaceitável", apesar de eu ter definido o acceptableContentTypescom umSet contendo o valor tipo de conteúdo em questão.

A solução para mim foi ajustar o código Swift para ser mais amigável ao Objective-C, eu acho :

serializer.acceptableContentTypes = NSSet(array: ["application/xml", "text/xml", "text/plain"]) as Set<NSObject>
mokagio
fonte
0

Uma boa pergunta sempre tem várias respostas, para reduzir e ajudá-lo a escolher a resposta certa, aqui também estou adicionando a minha. Eu testei e funciona bem.

AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:@"http://www.yourdomain.com/appname/data/ws/index.php/user/login/"]];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];

[manager POST:@"POST" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSString *json = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
    NSLog(@"%@", json);
    //Now convert json string to dictionary.
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"%@", error.localizedDescription);
}];
Hemang
fonte
-1
 UIImage *image = [UIImage imageNamed:@"decline_clicked.png"];
NSData *imageData = UIImageJPEGRepresentation(image,1);


NSString *queryStringss = [NSString stringWithFormat:@"http://119.9.77.121/lets_chat/index.php/webservices/uploadfile/"];
queryStringss = [queryStringss stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];

[MBProgressHUD showHUDAddedTo:self.view animated:YES];


[manager POST:queryStringss parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData)
 {


     [formData appendPartWithFileData:imageData name:@"fileName" fileName:@"decline_clicked.png" mimeType:@"image/jpeg"];



 }
      success:^(AFHTTPRequestOperation *operation, id responseObject)
 {



    NSDictionary *dict = [responseObject objectForKey:@"Result"];

    NSLog(@"Success: %@ ***** %@", operation.responseString, responseObject);
    [MBProgressHUD hideAllHUDsForView:self.view animated:YES];


 }
      failure:^(AFHTTPRequestOperation *operation, NSError *error)
 {
     [MBProgressHUD hideAllHUDsForView:self.view animated:YES];
     NSLog(@"Error: %@ ***** %@", operation.responseString, error);
 }];
Spydy
fonte