You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NSURLSessionDownloadTask遇服务器重定向时返回404状态码的解决问询

解决NSURLSessionDownloadTask重定向返回404的问题

问题出在默认NSURLSession的重定向处理逻辑上——它可能没有将原始请求的必要HTTP头(如User-Agent、Referer等)传递给重定向后的URL,而CDN服务器依赖这些头信息返回正确资源。浏览器会自动处理头信息的传递,但NSURLSession的默认行为不会。

要解决这个问题,你需要通过NSURLSessionTaskDelegate显式拦截并重写重定向请求,确保关键头信息被携带到新请求中:

修改后的代码实现

首先让你的类遵循NSURLSessionTaskDelegate协议:

@interface YourDownloadClass () <NSURLSessionTaskDelegate>
@end

@implementation YourDownloadClass

- (void)downloadImageWithURL:(NSURL *)imageURL {
    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration ephemeralSessionConfiguration];
    configuration.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
    configuration.URLCache = nil;
    configuration.timeoutIntervalForRequest = 5 * 60;
    
    // 设置session的delegate为当前类,使用主队列处理回调
    NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:[NSOperationQueue mainQueue]];

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:imageURL];
    // 可选:添加浏览器风格的User-Agent,部分CDN会验证此头
    [request setValue:@"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36" forHTTPHeaderField:@"User-Agent"];
    
    NSURLSessionDownloadTask *task = [session downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        NSInteger statusCode = 0;
        NSHTTPURLResponse *httpResponse = nil;
        if ([response isKindOfClass:NSHTTPURLResponse.class]) {
            httpResponse = (NSHTTPURLResponse *)response;
            statusCode = httpResponse.statusCode;
            if (statusCode == 200) {
                // 下载成功,处理文件逻辑
                NSLog(@"下载成功");
            } else {
                NSLog(@"请求失败,状态码:%ld", (long)statusCode);
            }
        } else {
            NSLog(@"下载错误:%@", error.localizedDescription);
        }
    }];

    [task resume];
}

// 拦截重定向请求,修改后继续
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willPerformHTTPRedirection:(NSHTTPURLResponse *)response newRequest:(NSURLRequest *)newRequest completionHandler:(void (^)(NSURLRequest * _Nullable))completionHandler {
    NSMutableURLRequest *modifiedRequest = [newRequest mutableCopy];
    
    // 将原始请求的所有HTTP头复制到重定向请求中
    NSURLRequest *originalRequest = task.originalRequest;
    for (NSString *headerKey in originalRequest.allHTTPHeaderFields) {
        [modifiedRequest setValue:originalRequest.allHTTPHeaderFields[headerKey] forHTTPHeaderField:headerKey];
    }
    
    // 允许重定向继续,使用修改后的请求
    completionHandler(modifiedRequest);
}

@end

关键说明

  1. 委托设置:必须为NSURLSession指定delegate才能拦截重定向事件,默认无delegate的会话会使用系统默认逻辑,可能丢失关键头信息。
  2. 头信息传递:通过复制原始请求的所有HTTP头到重定向请求,确保CDN服务器能识别请求的合法性。
  3. User-Agent适配:部分CDN会验证请求的User-Agent,添加浏览器风格的头可以避免被拦截。

如果问题仍然存在,可以检查重定向后的URL是否需要额外的头信息(如Referer),在willPerformHTTPRedirection方法中手动添加即可。

内容的提问来源于stack exchange,提问作者ashipma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 12:45:22