Żą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.

jaytrixz
źródło

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.

Andrei Neag
źródło
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.

Danpe
źródło
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"];
mharper
źródło
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.

Chris Prince
źródło
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.

dopcn
źródło
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"];
da Rocha Pires
źródło
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.

ABS
źródło
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);
    }];
}
Chrisrisick
źródło
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;
Hemang
źródło
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

uudaddy
źródło
1

Po prostu dodaj ten wiersz:

operation.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];
Elangovana
źródło
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>
mokagio
źródło
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);
}];
Hemang
źródło
-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);
 }];
Szpieg
źródło