iOS下載圖片失敗

来源:https://www.cnblogs.com/jingxin1992/archive/2018/09/05/9593725.html
-Advertisement-
Play Games

一、具體問題 開發的過程中,發現某個界面部分圖片的顯示出現了問題只顯示占點陣圖片,取出圖片的url在瀏覽器卻是能打開的,各種嘗試甚至找同行的朋友幫忙在他們項目里展示都會存在問題,最終發現通過第三方框架SDWebImage或者YYWebImage下載帶有逗號的url圖片鏈接都會下載失敗,在下載方法完成的 ...


一、具體問題  

  開發的過程中,發現某個界面部分圖片的顯示出現了問題只顯示占點陣圖片,取出圖片的url在瀏覽器卻是能打開的,各種嘗試甚至找同行的朋友幫忙在他們項目里展示都會存在問題,最終發現通過第三方框架SDWebImage或者YYWebImage下載帶有逗號的url圖片鏈接都會下載失敗,在下載方法完成的回調block裡面列印信息如下:

Error Domain=NSURLErrorDomain Code=403 "(null)"

  現列舉兩個不能正常展示的圖片url:

http://img1.imgtn.bdimg.com/it/u=3044191397,2911599132&fm=27&gp=0.jpg

http://img2.imgtn.bdimg.com/it/u=3509004173,840437551&fm=27&gp=0.jpg

  有興趣的小伙伴可以拿到自己的項目里試試

二、問題原因

  網上有小伙伴提出是因為缺少User-Agent用戶代理導致的。只有設置了用戶代理,才能訪問到這張帶有逗號的url圖片。至於這個用戶代理的格式,只要有值或者約定的特定格式字元串都可以。

三、具體解決

1.第三方框架YYWebImage

  找到YYWebImageManager.m文件,定位到設置http請求頭的屬性即_headers的地方,加入一個User-Agent的鍵值對,具體改動可以看下麵的方法

- (instancetype)initWithCache:(YYImageCache *)cache queue:(NSOperationQueue *)queue{
    self = [super init];
    if (!self) return nil;
    _cache = cache;
    _queue = queue;
    _timeout = 15.0;
    
    NSString *userAgent = @"";
    userAgent = [NSString stringWithFormat:@"%@/%@ (%@; iOS %@; Scale/%0.2f)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleExecutableKey] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleIdentifierKey], [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleVersionKey], [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemVersion], [[UIScreen mainScreen] scale]];
    
    if (userAgent) {
        if (![userAgent canBeConvertedToEncoding:NSASCIIStringEncoding]) {
            NSMutableString *mutableUserAgent = [userAgent mutableCopy];
            if (CFStringTransform((__bridge CFMutableStringRef)(mutableUserAgent), NULL, (__bridge CFStringRef)@"Any-Latin; Latin-ASCII; [:^ASCII:] Remove", false)) {
                userAgent = mutableUserAgent;
            }
        }
    }

    //帶有逗號的圖片url不顯示的問題,重要的是設置代理才能解決
    if (YYImageWebPAvailable()) {
        _headers = @{ @"Accept" : @"image/webp,image/*;q=0.8", @"User-Agent" : userAgent};
    } else {
        _headers = @{ @"Accept" : @"image/*;q=0.8", @"User-Agent" : userAgent};
    }
    return self;
}

2.第三方框架SDWebImage

  找到SDWebImageDownloader.m文件,也是定位到設置http請求頭的屬性即_HTTPHeaders的地方,加入一個User-Agent的鍵值對,具體改動可以看下麵的方法

- (id)init {
    if ((self = [super init])) {
        _operationClass = [SDWebImageDownloaderOperation class];
        _shouldDecompressImages = YES;
        _executionOrder = SDWebImageDownloaderFIFOExecutionOrder;
        _downloadQueue = [NSOperationQueue new];
        _downloadQueue.maxConcurrentOperationCount = 6;
        _URLCallbacks = [NSMutableDictionary new];
        /***********************/
        NSString *userAgent = @"";
        userAgent = [NSString stringWithFormat:@"%@/%@ (%@; iOS %@; Scale/%0.2f)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleExecutableKey] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleIdentifierKey], [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleVersionKey], [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemVersion], [[UIScreen mainScreen] scale]];
        
        if (userAgent) {
            if (![userAgent canBeConvertedToEncoding:NSASCIIStringEncoding]) {
                NSMutableString *mutableUserAgent = [userAgent mutableCopy];
                if (CFStringTransform((__bridge CFMutableStringRef)(mutableUserAgent), NULL, (__bridge CFStringRef)@"Any-Latin; Latin-ASCII; [:^ASCII:] Remove", false)) {
                    userAgent = mutableUserAgent;
                }
            }
        }
        /***********************/
#ifdef SD_WEBP
        _HTTPHeaders = [@{@"Accept": @"image/webp,image/*;q=0.8", userAgent : @"User-Agent"} mutableCopy];
#else
        _HTTPHeaders = [@{@"Accept": @"image/*;q=0.8", userAgent : @"User-Agent"} mutableCopy];
#endif
        _barrierQueue = dispatch_queue_create("com.hackemist.SDWebImageDownloaderBarrierQueue", DISPATCH_QUEUE_CONCURRENT);
        _downloadTimeout = 15.0;
    }
    return self;
}

或者是直接在UIImageView+WebCache.m文件中,在統一下載圖片入口最前面添加如下代碼

- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock {
    /***********************/
    NSString *userAgent = @"";
    userAgent = [NSString stringWithFormat:@"%@/%@ (%@; iOS %@; Scale/%0.2f)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleExecutableKey] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleIdentifierKey], [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleVersionKey], [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemVersion], [[UIScreen mainScreen] scale]];
    
    if (userAgent) {
        if (![userAgent canBeConvertedToEncoding:NSASCIIStringEncoding]) {
            NSMutableString *mutableUserAgent = [userAgent mutableCopy];
            if (CFStringTransform((__bridge CFMutableStringRef)(mutableUserAgent), NULL, (__bridge CFStringRef)@"Any-Latin; Latin-ASCII; [:^ASCII:] Remove", false)) {
                userAgent = mutableUserAgent;
            }
        }
        
        [[SDWebImageDownloader sharedDownloader] setValue:userAgent forHTTPHeaderField:@"User-Agent"];
    }
    /***********************/
    [self sd_cancelCurrentImageLoad];
    
    ........省略原源碼
}

3.其他第三方下載圖片的框架

  直接全局搜索字元串"Accept",因為雖然缺少設置User-Agent用戶代理,但是http請求頭一般都會有設置"Accept",所以定位後,直接再加一個User-Agent的鍵值對就可以了

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1. 引言 Pandas是一個開源的Python數據分析庫。Pandas把結構化數據分為了三類: Series,1維序列,可視作為沒有column名的、只有一個column的DataFrame; DataFrame,同Spark SQL中的DataFrame一樣,其概念來自於R語言,為多column ...
  • 使用SSMS資料庫管理工具修改UNIQUE約束 1、連接資料庫,選擇數據表-》右鍵點擊-》選擇設計(或者展開鍵,選擇要修改的鍵,右鍵點擊,選擇修改,後面步驟相同)。 2、選擇要修改的數據列-》右鍵點擊-》選擇索引/鍵。 3、在索引/鍵彈出框中-》選擇要修改的唯一約束-》選擇約束類型-》點擊列。 4、 ...
  • 一:個人看法 Mysql Group Replication 隨著5.7發佈3年了。作為技術愛好者。mgr 是繼 oracle database rac 之後。 又一個“真正” 的群集,怎麼做到“真正” ? 怎麼做到解決複製的延遲,怎麼做到強數據一致性?基於全局的GTID就能解決? 圍繞這些問題進行 ...
  • 最近很多人問小編現在學習大數據這麼多,他們都是如何學習的呢。很多初學者在萌生向大數據方向發展的想法之後,不免產生一些疑問,應該怎樣入門?應該學習哪些技術?學習路線又是什麼?今天小編特意為大家整理了一份大數據從入門到精通的學習路線。並且附帶學習資料和視頻。希望能夠幫助到大家。大數據學習資料分享群:11 ...
  • 從安裝操作系統到完成oracle安裝 1、安裝centos7 下載CentOS7 iso安裝包,配置虛擬機,由於只進行oracle安裝練習,隨便配置20G空間。選擇安裝文件。 開機,開始安裝系統: 直接選擇安裝選項: 等待載入: 選擇英文: 直接選自動分配磁碟: 選擇進行最小化安裝,節約空間。 設置 ...
  • React Native開發封裝Toast與載入Loading組件 在App開發中,我們避免不了使用的兩個組件,一個Toast,一個網路載入Loading,在RN開發中,也是一樣,React Native官方並沒有提供者這兩個常用組件,需要開發者自己根據需求來自定義。作者就在其他組件的基礎上在進行二 ...
  • 有時候在安裝apk的時候會出現解析軟體包出錯 (Android studio)解決方法如下: 關閉Instant Run功能: File-Settings-...看下圖: 將紅色框內的勾取消。 如果還是不行,那麼便在工程的gradle.properties里添加 android.injected.t ...
  • 1、檢查\app\src\main\AndroidMainfest.xml中是否有testOnly屬性為true,如果有去掉或者改為false 2、檢查Android Studio和gradle版本是否為alpha版本,換為穩定版本 3、檢查是否關閉Instant Run功能,關掉此功能 4、檢查是 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...