Solicitud fallida: tipo de contenido inaceptable: texto / html con AFNetworking 2.0

205

Estoy probando la nueva versión 2.0 de AFNetworking y obtengo el error anterior. ¿Alguna idea de por qué sucede esto? Aquí está mi 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];

Estoy usando Xcode 5.0.

Además, aquí está el mensaje de error:

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}

Acabo de ocultar el JSON usando kJSONlink. Esto debería devolver un JSON.

jaytrixz
fuente

Respuestas:

361

Esto significa que su servidor está enviando en "text/html"lugar de los tipos ya admitidos. Mi solución fue agregar "text/html"a acceptableContentTypesestablecer en AFURLResponseSerializationclase. Simplemente busque "aceptableContentTypes" y agréguelo @"text/html"al conjunto manualmente.

Por supuesto, la solución ideal es cambiar el tipo enviado desde el servidor, pero para eso tendrá que hablar con el equipo del servidor.

Andrei Neag
fuente
142
¡Gracias! Acabo de agregar este código para que funcione:op.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];
jaytrixz
13
Para PHP es tan fácil como agregar esto a la página: encabezado ("Tipo de contenido: aplicación / json"); (a menos que no sea una respuesta JSON, luego XML o algo así)
rckehoe
1
@rckehoe Gracias por esto, prefiero cambiar el encabezado de la página que acceptableContentTypes:)
Nick
43
Una alternativa al comentario de @jaytrixz es simplemente agregar un nuevo tipo de contenido a los ya existentes:op.responseSerializer.acceptableContentTypes = [op.responseSerializer.acceptableContentTypes setByAddingObject:@"text/html"];
mgarciaisaia
11
Código Swift:op.responseSerializer.acceptableContentTypes = NSSet(object: "text/html")
Husam
178

Configurar mi RequestOperationManagerserializador de respuestas para HTTPResponseSerializersolucionar el problema.

C objetivo

manager.responseSerializer = [AFHTTPResponseSerializer serializer];

Rápido

manager.responseSerializer = AFHTTPResponseSerializer()

Hacer este cambio significa que no necesito agregar acceptableContentTypesa cada solicitud que haga.

Danpe
fuente
2
Hice esto y bloquea mi aplicación. Volviendo al usoAFJSONResponseSerializer
jaytrixz
2
@jaytrixz Depende, si su servidor siempre responde con JSON, debe configurarlo responseSerializeren AFJSONResponseSerializer.
Danpe
2
Ahora recibirá el ResponseObject como NSData y deberá analizar el JSON en el bloque de éxito.
Cameron Lowell Palmer
1
Debido a que estoy usando pods, esta manera es mejor.
yong ho
@Danpe, Cómo convertir la línea de código anterior en Swift. Intenté con manager.responseSerializer = AFJSONResponseSerializer.serializer () pero no lo uso.
Ganesh Guturi
72

Llevé la respuesta / comentario de @jaytrixz un paso más allá y agregué "text / html" al conjunto de tipos existente. De esa forma, cuando lo arreglen en el lado del servidor a "application / json" o "text / json", afirmo que funcionará a la perfección.

  manager.responseSerializer.acceptableContentTypes = [manager.responseSerializer.acceptableContentTypes setByAddingObject:@"text/html"];
mharper
fuente
2
Convenido. La respuesta aceptada a esta pregunta tiene un gran defecto, ya que crea una bomba de tiempo que explotará cuando el lado del servidor esté arreglado para devolver el tipo de contenido correcto.
Eric Goldberg
Esto parece correcto en teoría, pero ¿alguien realmente ha probado esto?
Minimi
32

En el lado del servidor, agregué:

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

en mi código .php y esto también solucionó el problema.

Chris Prince
fuente
3
if(!headers_sent() ) { header('Content-Type: application/json'); } Es una buena solución
elliotrock 01 de
17

Resuelvo este problema desde una perspectiva diferente.

Creo que si el servidor envía datos JSON con Content-Type: text/htmlencabezado. No significa que el chico del servidor pretendía enviarte un html pero cambió accidentalmente a JSON. Significa que al servidor no le importa cuál es el Content-Typeencabezado. Entonces, si al chico del servidor no le importa el lado del cliente, será mejor que ignore el Content-Typeencabezado también. Para ignorar el Content-Typeencabezado, regístreseAFNetworking

manager.responseSerializer.acceptableContentTypes = nil;

De esta forma, el AFJSONResponseSerializer(el predeterminado) serializará los datos JSON sin verificar el Content-Typeencabezado de respuesta.

dopcn
fuente
Exactamente correcto Al ignorar el tipo de contenido, no recibo mi contenido como un código hexadecimal ni como una respuesta nula fallida. ¡Esto funciona muy bien! Gracias
Brandon
7

Una forma sencilla de permitir recibir el tipo de contenido "text / plain":

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

Del mismo modo, si desea habilitar el tipo de contenido "text / html":

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

Intenté debajo de la línea según la respuesta de @Andrie pero no funcionó,

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

así que después de buscar más, trabajé para que funcionara con éxito.

Aquí está mi fragmento 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 esto ayude a alguien por ahí.

abdominales
fuente
1
+1. Esta es definitivamente la solución. Dado que debe establecer el tipo de contenido aceptable tanto en el serializador si se trata de un serializador JSON (que normalmente usa "application / json") como la operación. De lo contrario, obtendrá una configuración de error solo en la operación.
loretoparisi
3

Esto es lo único que encontré que funciona

-(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
fuente
3

Si alguien está usando AFHTTPSessionManager, uno puede hacer esto para resolver el problema,

Subclase AFHTTPSessionManagerdonde estoy haciendo esto,

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

En mi caso, no tengo control sobre la configuración del servidor, pero sé que espera "application / json" para "Content-Type". Hice esto en el lado del cliente iOS:

manager.requestSerializer = [AFJSONRequestSerializer serializer];

consulte el error de tipo de contenido de AFNetworking versión 2

uudaddy
fuente
1

Solo agrega esta línea:

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

Tuve un problema similar al trabajar con AFNetworking desde una base de código Swift, así que lo dejo aquí en el caso remoto de que alguien tenga tanta mala suerte como yo tener que trabajar en una configuración de este tipo. Si es así, te siento amigo, ¡mantente fuerte!

La operación estaba fallando debido al "tipo de contenido inaceptable", a pesar de que en realidad configuré acceptableContentTypescon un Setvalor de tipo de contenido en cuestión.

La solución para mí fue ajustar el código Swift para que sea más amigable con Objective-C, supongo :

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

Una buena pregunta siempre tiene múltiples respuestas, para reducir y ayudarlo a elegir la respuesta correcta, aquí también estoy agregando la mía. Lo he probado y funciona bien.

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
fuente
-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);
 }];
Espía
fuente