1、提出問題
Domain=com.alamofire.error.serialization.response Code=-1016,unacceptable content-type: content-type: application/json。
這是一次調(diào)試中遇到的問題,首先我想到的是不是我在設置AFN 的這個屬性的時候有問題_manager.responseSerializer.acceptableContentTypes檢查一下代碼
_manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/html", nil];
的確設置了application/json的屬性啊,啥還是有問題的。但是我在抓包工具上的確看到的json數(shù)據(jù),很費解,我試著去掉抓包工具,換個手機試試,用模擬器試試,慌亂的時候,總覺得是設備或者其他的問題。事實證明是愚蠢的。
2、代碼調(diào)試
我想,解決問題的根本辦法還是去代碼里面看看吧,與是斷點就跟到了這里
- (BOOL)validateResponse:(NSHTTPURLResponse *)response
data:(NSData *)data
error:(NSError * __autoreleasing *)error
{
BOOL responseIsValid = YES;
NSError *validationError = nil;
if (response && [response isKindOfClass:[NSHTTPURLResponse class]]) {
if (self.acceptableContentTypes && ![self.acceptableContentTypes containsObject:[response MIMEType]] &&
!([response MIMEType] == nil && [data length] == 0)) {
if ([data length] > 0 && [response URL]) {
NSMutableDictionary *mutableUserInfo = [@{
NSLocalizedDescriptionKey: [NSString stringWithFormat:NSLocalizedStringFromTable(@"Request failed: unacceptable content-type: %@", @"AFNetworking", nil), [response MIMEType]],
NSURLErrorFailingURLErrorKey:[response URL],
AFNetworkingOperationFailingURLResponseErrorKey: response,
} mutableCopy];
if (data) {
mutableUserInfo[AFNetworkingOperationFailingURLResponseDataErrorKey] = data;
}
validationError = AFErrorWithUnderlyingError([NSError errorWithDomain:AFURLResponseSerializationErrorDomain code:NSURLErrorCannotDecodeContentData userInfo:mutableUserInfo], validationError);
}
responseIsValid = NO;
}
if (self.acceptableStatusCodes && ![self.acceptableStatusCodes containsIndex:(NSUInteger)response.statusCode] && [response URL]) {
NSMutableDictionary *mutableUserInfo = [@{
NSLocalizedDescriptionKey: [NSString stringWithFormat:NSLocalizedStringFromTable(@"Request failed: %@ (%ld)", @"AFNetworking", nil), [NSHTTPURLResponse localizedStringForStatusCode:response.statusCode], (long)response.statusCode],
NSURLErrorFailingURLErrorKey:[response URL],
AFNetworkingOperationFailingURLResponseErrorKey: response,
} mutableCopy];
if (data) {
mutableUserInfo[AFNetworkingOperationFailingURLResponseDataErrorKey] = data;
}
validationError = AFErrorWithUnderlyingError([NSError errorWithDomain:AFURLResponseSerializationErrorDomain code:NSURLErrorBadServerResponse userInfo:mutableUserInfo], validationError);
responseIsValid = NO;
}
}
if (error && !responseIsValid) {
*error = validationError;
}
return responseIsValid;
}
在AFURLResponseSerialization文件中,116行,有這樣一個判斷
![self.acceptableContentTypes containsObject:[response MIMEType]],于是有了這樣的[response MIMEType] = "content-type: application/json",好吧,服務器的哥們content type 設置成了"content-type: application/json",多了一個“content-type:”。問題找到了。自然解決也就是告訴他一下的事情。
3、 反思
為啥這個問題解決花了比較長的時間
- 遇到問題不仔細看日志,其實日志上寫的很清晰
unacceptable content-type: content-type: application/json。讀的時候囫圇吞棗,只看后面沒看前面 - 過分信任工具,覺得charles和安卓都能解析到、那么就是自己代碼的問題。
- 基礎知識不扎實,遇到問題不能一下定位清楚。想各種與之無關的方法去解決問題。
4、反思后
MIME, Mutipurpose Internet Mail Extensions,多用途 Internet 郵箱擴展。MIME 是描述消息內(nèi)容類型的 internet 標準。在創(chuàng)建之初,是為了在發(fā)送電子郵件時附加多媒體數(shù)據(jù),讓郵件客戶程序根據(jù)其類型進行處理?,F(xiàn)在 MIME TYPE 被 HTTP 協(xié)議支持后,使得HTTP能夠傳輸各種各樣的文件。
瀏覽器與 MIME-TYPE
瀏覽器通過 MIME TYE,也就是該資源的媒體類型,來決定以什么形式顯示數(shù)據(jù)。
媒體類型通常是通過 HTTP 協(xié)議,由 Web 服務器請求頭中的 Content-Type 來告知瀏覽器數(shù)據(jù)類型的,比如:
Content-Type: text/HTML
表示內(nèi)容是 text/HTML 類型,也就是超文本文件。注意,必須是 "text/HTML" 而不是 "HTML/text".因為 MIME 是經(jīng)過 ietf 組織協(xié)商,以 RFC 的形式發(fā)布在網(wǎng)上的。
自定義的類型
需要注意的是:只有一些在互聯(lián)網(wǎng)上獲得廣泛應用的格式才會獲得一個 MIME Type,如果是某個客戶端自己定義的格式,一般只能以 application/x- 開頭。
Internet 中有一個專門組織來對 MIME 標準進行修訂,但是由于 Internet 發(fā)展過快,很多應用程序便使用在類別中以 x- 開頭的方法標識這個類別還沒有成為標準,例如 x-gzip,x-tar等。
5 、后續(xù)計劃
這幾天遇到了很多網(wǎng)絡知識不足造成的問題,所以計劃惡補一下這塊知識。