Échec de la demande: type de contenu inacceptable: texte / html à l'aide d'AFNetworking 2.0

205

J'essaie la nouvelle version 2.0 d'AFNetworking et j'obtiens l'erreur ci-dessus. Une idée pourquoi cela se produit? Voici mon code:

    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];

J'utilise Xcode 5.0.

Voici également le message d'erreur:

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}

Je viens de cacher le JSON en utilisant kJSONlink. Cela devrait retourner un JSON.

jaytrixz
la source

Réponses:

361

Cela signifie que votre serveur envoie "text/html"au lieu des types déjà pris en charge. Ma solution était d’ajouter "text/html"àacceptableContentTypes mettre en AFURLResponseSerializationclasse. Recherchez simplement "acceptableContentTypes" et ajoutez- @"text/html"le manuellement.

Bien sûr, la solution idéale est de changer le type envoyé depuis le serveur, mais pour cela, vous devrez parler avec l'équipe du serveur.

Andrei Neag
la source
142
Merci! Je viens d'ajouter ce code pour le faire fonctionner:op.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];
jaytrixz
13
Pour PHP, c'est aussi simple que d'ajouter ceci à la page: header ("Content-Type: application / json"); (sauf s'il ne s'agit pas d'une réponse JSON, alors XML ou quelque chose du
genre
1
@rckehoe Merci pour cela - il est préférable de changer l'en-tête de la page que acceptableContentTypes:)
Nick
43
Une alternative au commentaire @jaytrixz consiste simplement à ajouter un nouveau type de contenu à ceux déjà existants:op.responseSerializer.acceptableContentTypes = [op.responseSerializer.acceptableContentTypes setByAddingObject:@"text/html"];
mgarciaisaia
11
Code Swift:op.responseSerializer.acceptableContentTypes = NSSet(object: "text/html")
Husam
178

Configuration de mon RequestOperationManagersérialiseur de réponse pour HTTPResponseSerializerrésoudre le problème.

Objectif c

manager.responseSerializer = [AFHTTPResponseSerializer serializer];

Rapide

manager.responseSerializer = AFHTTPResponseSerializer()

Faire ce changement signifie que je n'ai pas besoin d'ajouter acceptableContentTypesà chaque demande que je fais.

Danpe
la source
2
J'ai fait ça et ça plante mon application. Revenir à l'utilisationAFJSONResponseSerializer
jaytrixz
2
@jaytrixz Cela dépend, Si votre serveur répond toujours avec JSON, vous devez définir le responseSerializersur AFJSONResponseSerializer.
Danpe
2
Vous allez maintenant recevoir le responseObject en tant que NSData et devez analyser le JSON dans le bloc de réussite.
Cameron Lowell Palmer
1
Parce que j'utilise des pods, c'est mieux ainsi.
yong ho
@Danpe, Comment convertir la ligne de code ci-dessus en Swift. J'ai essayé avec manager.responseSerializer = AFJSONResponseSerializer.serializer () mais sans utilité.
Ganesh Guturi
72

J'ai poussé la réponse / le commentaire de @ jaytrixz un peu plus loin et j'ai ajouté "text / html" à l'ensemble de types existant. De cette façon, quand ils le fixent côté serveur sur "application / json" ou "text / json", je prétends que cela fonctionnera de manière transparente.

  manager.responseSerializer.acceptableContentTypes = [manager.responseSerializer.acceptableContentTypes setByAddingObject:@"text/html"];
mharper
la source
2
D'accord. La réponse acceptée à cette question a un énorme défaut en ce qu'elle crée une bombe à retardement qui explosera lorsque le côté serveur sera corrigé pour renvoyer le type de contenu correct.
Eric Goldberg
Cela semble juste en théorie, mais quelqu'un a-t-il réellement testé cela?
Minimi
32

Côté serveur, j'ai ajouté:

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

dans mon code .php et cela a également résolu le problème.

Chris Prince
la source
3
if(!headers_sent() ) { header('Content-Type: application/json'); } Est une bonne solution
elliotrock
17

Je résous ce problème sous un angle différent.

Je pense que si le serveur envoie des données JSON avec en- Content-Type: text/htmltête. Cela ne signifie pas que le serveur avait l'intention de vous envoyer du HTML mais qu'il a accidentellement changé en JSON. Cela signifie que le serveur ne se soucie pas de ce qu'est l'en- Content-Typetête. Donc, si le serveur ne se soucie pas du côté client, il vaut mieux ignorer également l'en- Content-Typetête. Pour ignorer l' Content-Typeenregistrement d'en-têteAFNetworking

manager.responseSerializer.acceptableContentTypes = nil;

De cette façon, le AFJSONResponseSerializer(celui par défaut) sérialise les données JSON sans archiver l' Content-Typeen-tête de réponse.

dopcn
la source
Exactement correct. En ignorant le type de contenu, je ne reçois pas mon contenu sous forme de code hexadécimal, ni de réponse nulle échouée. Cela fonctionne très bien! Merci
Brandon
7

Un moyen simple pour permettre de recevoir le type de contenu "texte / simple":

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

De même si vous souhaitez activer le type de contenu "text / html":

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

J'ai essayé la ligne ci-dessous selon la réponse @Andrie mais je n'ai pas fonctionné,

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

donc après avoir chassé plus, j'ai travaillé pour le faire fonctionner avec succès.

Voici mon extrait de code.

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;

J'espère que cela aidera quelqu'un là-bas.

abdos
la source
1
+1. C'est définitivement la solution. Étant donné que vous devez définir le type de contenu acceptable à la fois sur le sérialiseur s'il s'agit d'un sérialiseur JSON (qui utilise normalement "application / json") et l'opération. Sinon, vous obtiendrez une erreur sur les paramètres de fonctionnement uniquement.
loretoparisi
3

C'est la seule chose que j'ai trouvé pour travailler

-(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
la source
3

Si quelqu'un utilise AFHTTPSessionManager alors on peut faire comme ça pour résoudre le problème,

Je sous-classe AFHTTPSessionManageroù je fais comme ça,

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

Dans mon cas, je n'ai aucun contrôle sur les paramètres du serveur, mais je sais qu'il attend "application / json" pour "Content-Type". Je l'ai fait du côté client iOS:

manager.requestSerializer = [AFJSONRequestSerializer serializer];

se référer à l' erreur de type de contenu AFNetworking version 2

uudaddy
la source
1

Ajoutez simplement cette ligne:

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

J'ai eu un problème similaire avec AFNetworking à partir d'une base de code Swift, donc je laisse cela ici dans le cas éloigné, quelqu'un est aussi malchanceux que moi d'avoir à travailler dans une telle configuration. Si tu l'es, je te sens mon pote, reste fort!

L'opération a échoué en raison d'un "type de contenu inacceptable", malgré le fait que je définisse le acceptableContentTypesavec un Setcontenant la valeur du type de contenu en question.

La solution pour moi a été de modifier le code Swift pour qu'il soit plus convivial pour Objective-C, je suppose :

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

Une bonne question a toujours plusieurs réponses, pour réduire et vous aider à choisir la bonne réponse, ici j'ajoute la mienne aussi. Je l'ai testé et cela fonctionne 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
la source
-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
la source