Żądanie nie powiodło się: niedopuszczalny typ zawartości: tekst / HTML przy użyciu AFNetworking 2.0


205

Wypróbowuję nową wersję 2.0 AFNetworking i otrzymuję powyższy błąd. Jakiś pomysł dlaczego tak się dzieje? Oto mój kod:

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

Używam Xcode 5.0.

Oto komunikat o błędzie:

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}

Właśnie ukryłem JSON za pomocą kJSONlink. To powinno zwrócić JSON.

Odpowiedzi:


361

Oznacza to, że serwer wysyła "text/html"zamiast już obsługiwanych typów. Moim rozwiązaniem było dodanie "text/html"do acceptableContentTypeszestawu w AFURLResponseSerializationklasie. Wystarczy wyszukać „akceptowalne typy treści” i dodać @"text/html"ręcznie do zestawu.

Oczywiście idealnym rozwiązaniem jest zmiana typu wysyłanego z serwera, ale w tym celu będziesz musiał porozmawiać z zespołem serwera.


142
Dzięki! Właśnie dodałem ten kod, aby działał:op.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];
— jaytrixz

13
W przypadku PHP jest to tak proste, jak dodanie tego do nagłówka page: („Content-Type: application / json”); (chyba że nie jest to odpowiedź JSON, a następnie XML lub coś takiego)
— rckehoe

1
@rckehoe Dzięki za to - zdecydowanie wolę zmienić nagłówek strony niż acceptableContentTypes:)
— Nick

43
Alternatywą dla komentarza @jaytrixz jest dodanie nowego typu treści do już istniejących:op.responseSerializer.acceptableContentTypes = [op.responseSerializer.acceptableContentTypes setByAddingObject:@"text/html"];
— mgarciaisaia

11
Szybki kod:op.responseSerializer.acceptableContentTypes = NSSet(object: "text/html")
— Husam

178

Ustawienie mojego RequestOperationManagerSerializatora odpowiedzi w celu HTTPResponseSerializerrozwiązania problemu.

Cel C

manager.responseSerializer = [AFHTTPResponseSerializer serializer];

Szybki

manager.responseSerializer = AFHTTPResponseSerializer()

Dokonanie tej zmiany oznacza, że ​​nie muszę dodawać acceptableContentTypesdo każdej składanej prośby.


2
Zrobiłem to i powoduje awarię mojej aplikacji. Wracając do używaniaAFJSONResponseSerializer
— jaytrixz,

2
@jaytrixz To zależy, Jeśli serwer zawsze reaguje z JSON należy ustawić responseSerializersię AFJSONResponseSerializer.
— Danpe,

2
Otrzymasz teraz responseObject jako NSData i musisz przeanalizować JSON w bloku powodzenia.
— Cameron Lowell Palmer

1
Ponieważ używam strąków, więc ten sposób jest lepszy.
— yong ho

@Danpe, Jak przekonwertować powyższą linię kodu na Swift. Próbowałem z manage.responseSerializer = AFJSONResponseSerializer.serializer (), ale bez sensu.
— Ganesh Guturi

72

Posunąłem odpowiedź / komentarz @ jaytrixz o krok dalej i dodałem „text / html” do istniejącego zestawu typów. W ten sposób, gdy naprawią go po stronie serwera do „application / json” lub „text / json”, twierdzę, że będzie działał bezproblemowo.

  manager.responseSerializer.acceptableContentTypes = [manager.responseSerializer.acceptableContentTypes setByAddingObject:@"text/html"];

2
Zgoda. Przyjęta odpowiedź na to pytanie ma ogromną wadę, ponieważ tworzy bombę zegarową, która wybuchnie, gdy strona serwera zostanie naprawiona, aby zwrócić prawidłowy typ zawartości.
— Eric Goldberg,

To teoretycznie wydaje się słuszne, ale czy ktoś faktycznie to przetestował?
— Minimi

32

Po stronie serwera dodałem:

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

do mojego kodu .php, co również rozwiązało problem.


3
if(!headers_sent() ) { header('Content-Type: application/json'); } To niezła poprawka
— elliotrock,

17

Rozwiązuję ten problem z innej perspektywy.

Myślę, że jeśli serwer wysyła dane JSON z Content-Type: text/htmlnagłówkiem. Nie oznacza to, że serwer zamierzał wysłać ci trochę html, ale przypadkowo zmienił się na JSON. To znaczy, że serwer nie przejmuje się tym, co to Content-Typejest nagłówek. Więc jeśli serwer nie dba o to po stronie klienta, lepiej zignoruj ​​również Content-Typenagłówek. Aby zignorować Content-Typenagłówek, zaloguj sięAFNetworking

manager.responseSerializer.acceptableContentTypes = nil;

W ten sposób AFJSONResponseSerializer(domyślny) serializuje dane JSON bez sprawdzania Content-Typenagłówka odpowiedzi.


Dokładnie poprawne. Ignorując typ zawartości, nie otrzymuję treści jako kodu szesnastkowego ani jako nieudanej odpowiedzi zerowej. To działa świetnie! Dziękuję
— Brandon,

7

Prosty sposób na włączenie odbierania typu „tekst / zwykły”:

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

Podobnie jeśli chcesz włączyć typ zawartości „text / html”:

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

5

Próbowałem poniżej linii zgodnie z odpowiedzią @Andrie, ale nie działałem,

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

więc po dłuższym polowaniu zacząłem pracować nad tym, aby skutecznie działać.

Oto mój wycinek kodu.

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;

Mam nadzieję, że to pomoże komuś tam.


1
+1. To jest zdecydowanie rozwiązanie. Ponieważ musisz ustawić akceptowalny typ zawartości zarówno na Serializatorze, jeśli jest to serializator JSON (który zwykle używa „application / json”) i operacja. W przeciwnym razie ustawienia błędu pojawią się tylko podczas pracy.
— loretoparisi

3

To jedyna rzecz, którą znalazłem do pracy

-(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);
    }];
}

3

Jeśli ktoś używa, AFHTTPSessionManagermożna to zrobić w ten sposób, aby rozwiązać problem,

Podklasowałem, AFHTTPSessionManagergdzie to robię,

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

2

W moim przypadku nie mam kontroli nad ustawieniami serwera, ale wiem, że oczekuje on „application / json” dla „Content-Type”. Zrobiłem to po stronie klienta iOS:

manager.requestSerializer = [AFJSONRequestSerializer serializer];

patrz błąd typu treści AFNetworking wersja 2


1

Po prostu dodaj ten wiersz:

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

0

Miałem w jakiś sposób podobny problem podczas pracy z AFNetworking z bazy kodu Swift, więc zostawiam to tutaj w zdalnej sprawie, gdy ktoś jest tak pechowy jak ja, że ​​muszę pracować w takiej konfiguracji. Jeśli tak, czuję, że jesteś kumplem, bądź silny!

Operacja została braku powodu „niedopuszczalnego content-type”, mimo mnie rzeczywiście ustawienie acceptableContentTypesz Setzawierającego treść wartość rodzaju.

Rozwiązaniem dla mnie było ulepszenie kodu Swift, aby był bardziej przyjazny dla Objective-C, tak myślę :

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

0

Dobre pytanie zawsze zawiera wiele odpowiedzi, aby je zmniejszyć i pomóc wybrać właściwą odpowiedź, tutaj też dodam własną. Przetestowałem to i działa dobrze.

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

-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);
 }];
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.