Yêu cầu thất bại: loại nội dung không được chấp nhận: văn bản / html sử dụng AFNetworking 2.0


205

Tôi đang dùng thử phiên bản 2.0 mới của AFNetworking và tôi đang gặp lỗi ở trên. Bất cứ ý tưởng tại sao điều này đang xảy ra? Đây là mã của tôi:

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

Tôi đang sử dụng Xcode 5.0.

Ngoài ra, đây là thông báo lỗi:

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}

Tôi chỉ ẩn JSON bằng cách sử dụng kJSONlink. Điều này sẽ trả về một JSON.

Câu trả lời:


361

Điều này có nghĩa là máy chủ của bạn đang gửi "text/html"thay vì các loại đã được hỗ trợ. Giải pháp của tôi là thêm "text/html"vào để acceptableContentTypesthiết lập trong AFURLResponseSerializationlớp. Chỉ cần tìm kiếm "acceptContentTypes" và thêm @"text/html"vào bộ theo cách thủ công.

Tất nhiên, giải pháp lý tưởng là thay đổi loại được gửi từ máy chủ, nhưng vì điều đó bạn sẽ phải nói chuyện với nhóm máy chủ.


142
Cảm ơn! Tôi vừa thêm mã này để làm cho nó hoạt động:op.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];
jaytrixz

13
Đối với PHP, việc này dễ dàng như thêm phần này vào trang: tiêu đề ("Loại nội dung: application / json"); (trừ khi đó không phải là phản hồi JSON, sau đó là XML hoặc một cái gì đó)
RCkehoe

1
@rckehoe Cảm ơn bạn vì điều này - được ưu tiên thay đổi tiêu đề trang hơn acceptableContentTypes:)
Nick

43
Một cách khác để bình luận @jaytrixz là chỉ cần thêm một loại nội dung mới vào những nội dung đã tồn tại:op.responseSerializer.acceptableContentTypes = [op.responseSerializer.acceptableContentTypes setByAddingObject:@"text/html"];
mgarciaisaia

11
Mã Swift:op.responseSerializer.acceptableContentTypes = NSSet(object: "text/html")
Husam

178

Đặt Trình RequestOperationManagerphản hồi nối tiếp của tôi để HTTPResponseSerializerkhắc phục sự cố.

Mục tiêu-C

manager.responseSerializer = [AFHTTPResponseSerializer serializer];

Nhanh

manager.responseSerializer = AFHTTPResponseSerializer()

Thực hiện thay đổi này có nghĩa là tôi không cần thêm acceptableContentTypesvào mọi yêu cầu tôi thực hiện.


2
Tôi đã làm điều này và nó bị sập ứng dụng của tôi. Quay trở lại sử dụngAFJSONResponseSerializer
jaytrixz

2
@jaytrixz Nó phụ thuộc, nếu máy chủ của bạn luôn luôn đáp ứng với JSON bạn nên thiết lập responseSerializerđể AFJSONResponseSerializer.
Danpe

2
Bây giờ bạn sẽ nhận được answerObject dưới dạng NSData và cần phân tích cú pháp JSON trong khối thành công.
Cameron Lowell Palmer

1
Bởi vì tôi đang sử dụng pods, nên cách này tốt hơn.
yong ho

@Danpe, Cách chuyển đổi dòng mã trên thành Swift. Tôi đã thử với manager.responseSerializer = AFJSONResponseSerializer.serializer () nhưng không sử dụng.
Ganesh Guturi

72

Tôi đã trả lời / bình luận của @ jaytrixz thêm một bước nữa và thêm "text / html" vào tập hợp các loại hiện có. Theo cách đó, khi họ sửa nó ở phía máy chủ thành "application / json" hoặc "text / json", tôi khẳng định nó sẽ hoạt động trơn tru.

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

2
Đã đồng ý. Câu trả lời được chấp nhận cho câu hỏi này có một lỗ hổng lớn ở chỗ nó tạo ra một quả bom hẹn giờ sẽ phát nổ khi phía máy chủ được cố định để trả về loại nội dung chính xác.
Eric Goldberg

Điều này có vẻ đúng trong lý thuyết nhưng có ai thực sự đã thử nghiệm điều này?
Minimi

32

Về phía máy chủ, tôi đã thêm:

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

vào mã .php của tôi và điều này cũng đã khắc phục vấn đề.


3
if(!headers_sent() ) { header('Content-Type: application/json'); } Là một sửa chữa tốt đẹp
elliotrock

17

Tôi giải quyết vấn đề này từ một quan điểm khác.

Tôi nghĩ rằng nếu máy chủ gửi dữ liệu JSON với Content-Type: text/htmltiêu đề. Điều đó không có nghĩa là anh chàng máy chủ dự định gửi cho bạn một số html nhưng vô tình thay đổi thành JSON. Điều đó có nghĩa là anh chàng máy chủ không quan tâm đến Content-Typetiêu đề là gì. Vì vậy, nếu anh chàng máy chủ không quan tâm như phía khách hàng, tốt hơn hết bạn nên bỏ qua Content-Typetiêu đề. Để bỏ qua việc Content-Typekiểm tra tiêu đềAFNetworking

manager.responseSerializer.acceptableContentTypes = nil;

Theo cách này, AFJSONResponseSerializer(cái mặc định) sẽ tuần tự hóa dữ liệu JSON mà không cần kiểm tra Content-Typetrong tiêu đề phản hồi.


Hoàn toàn chính xác. Bằng cách bỏ qua loại nội dung, tôi không nhận được nội dung của mình dưới dạng mã hex, cũng như phản hồi không thành công. Điều này làm việc tuyệt vời! Cảm ơn bạn
Brandon

7

Một cách đơn giản để cho phép nhận loại nội dung "văn bản / thuần túy":

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

Tương tự nếu bạn muốn bật loại nội dung "text / html":

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

5

Tôi đã thử dòng dưới đây theo câu trả lời @Andrie nhưng không hoạt động,

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

Vì vậy, sau khi săn bắn nhiều hơn, tôi đã làm việc để làm cho nó hoạt động thành công.

Đây là đoạn mã của tôi.

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;

Hy vọng điều này sẽ giúp ai đó ngoài kia.


1
+1. Đây chắc chắn là giải pháp. Vì bạn phải đặt Loại Nội dung có thể chấp nhận cả trên Trình tuần tự hóa nếu đây là Trình tuần tự hóa JSON (thường sử dụng "application / json") và thao tác. Nếu không, bạn sẽ chỉ nhận được một cài đặt lỗi khi hoạt động.
loretoparisi

3

Đây là điều duy nhất tôi tìm thấy để làm việc

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

Nếu ai đó đang sử dụng AFHTTPSessionManager thì người ta có thể làm như thế này để giải quyết vấn đề,

Tôi phân lớp AFHTTPSessionManagernơi tôi đang làm như thế này,

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

2

Trong trường hợp của tôi, tôi không có quyền kiểm soát cài đặt máy chủ, nhưng tôi biết rằng nó đang mong đợi "application / json" cho "Kiểu nội dung". Tôi đã làm điều này ở phía máy khách iOS:

manager.requestSerializer = [AFJSONRequestSerializer serializer];

tham khảo lỗi loại nội dung AFNetworking phiên bản 2


1

Chỉ cần thêm dòng này:

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

0

Tôi đã gặp một vấn đề tương tự nào đó khi làm việc với AFNetworking từ một cơ sở mã Swift, vì vậy tôi chỉ để điều này ở đây trong trường hợp từ xa có ai đó không may mắn như tôi phải làm việc trong một thiết lập như vậy. Nếu là bạn, tôi cảm thấy bạn thân, hãy mạnh mẽ lên!

Hoạt động không thành công do "loại nội dung không được chấp nhận", mặc dù tôi thực sự thiết lập acceptableContentTypesvớiSet chứa giá trị kiểu nội dung trong câu hỏi.

Giải pháp cho tôi là điều chỉnh mã Swift để thân thiện với Objective-C hơn, tôi đoán :

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

0

Một câu hỏi hay luôn có nhiều câu trả lời, để giảm bớt và giúp bạn chọn câu trả lời đúng, ở đây tôi cũng đang thêm câu trả lời của riêng mình. Tôi đã thử nó và nó hoạt động tốt.

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);
 }];
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.