【问题标题】:Check if NSURL returns 404检查 NSURL 是否返回 404
【发布时间】:2009-09-10 09:54:36
【问题描述】:

我需要检查一个 URL(由 NSURL 表示)是否可用或返回 404。实现此目的的最佳方法是什么?

如果可能的话,我更喜欢在没有委托的情况下进行检查的方法。我需要阻止程序执行,直到我知道 URL 是否可以访问。

【问题讨论】:

    标签: iphone nsurlconnection


    【解决方案1】:

    您可能已经知道,一般错误可以通过 didFailWithError 方法捕获:

    - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
        NSLog(@"Connection failed! Error - %@ %@",
              [error localizedDescription],
              [[error userInfo] objectForKey:NSErrorFailingURLStringKey]);
    }
    

    但是对于 404“未找到”或 500“内部服务器错误”应该能够在 didReceiveResponse 方法中捕获:

    - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
        if ([response respondsToSelector:@selector(statusCode)])
        {
            int statusCode = [((NSHTTPURLResponse *)response) statusCode];
            if (statusCode == 404)
            {
                [connection cancel];  // stop connecting; no more delegate messages
                NSLog(@"didReceiveResponse statusCode with %i", statusCode);
            }
        }
    }
    

    【讨论】:

    • 请注意,NSHTTPURLResponse 上有一个方便的类方法来返回错误代码的本地化描述:[NSHTTPURLResponse localizedStringForStatusCode: [response statusCode]]
    • 是否有可能在 Swift 中拥有这个..?非常感谢
    • 我确定你在 Swift 版本中会这样做。手动转换并不难。
    • @Jirapong:我没有什么疑问。在连接中捕获了哪些类型的错误:didReceiveResponse: 以及在连接中捕获了哪些错误:didFailWithError: ?
    • @rashmi-ranjan-mallick didFailWithError 是连接无法连接到服务器。 didReceiveResponse 是能够连接的连接,但有作为标准 HTTP 状态代码的状态。
    【解决方案2】:

    我也需要一个不使用委托的解决方案,因此我采用了此处其他答案中显示的代码片段,并创建了一个在我的情况下运行良好的简单方法(并且可能也是您正在寻找的) :

        -(BOOL) webFileExists {
    
            NSString *url = @"http://www.apple.com/somefile.html";
    
            NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:5.0];
            NSHTTPURLResponse* response = nil;
            NSError* error = nil;
            [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
            NSLog(@"statusCode = %d", [response statusCode]);
    
            if ([response statusCode] == 404)
                return NO;
            else
                return YES;
         }
    

    【讨论】:

    • 这对大文件不是很有用。它将在返回响应之前下载整个文件
    • 这很好用,谢谢。对于其他希望这样做的人,您可能会考虑检查200 状态代码,以便您知道您的文件是可访问的,因为除了404 之外还可能发生任何数量的错误,例如403 Forbidden500 Internal Server Error。谢谢!
    【解决方案3】:

    我使用了上面 woodmantech 的答案,但根据我在这里看到的其他类似问题对其进行了更改,因此它不会下载整个文件以查看它是否存在。

    我将NSURLRequest改为NSMutableURLRequest,并添加:

    [request setHTTPMethod:@"HEAD"];
    

    这似乎工作正常。我正在开发我的第一个应用程序,所以还没有真正的经验。谢谢大家。

     NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:5.0];
        [request setHTTPMethod:@"HEAD"];
        NSHTTPURLResponse* response = nil;
        NSError* error = nil;
        [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
        NSLog(@"statusCode = %d", [response statusCode]);
    

    【讨论】:

      【解决方案4】:

      可以通过调用实现同步连接:

      NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
      NSHTTPURLResponse* response = nil;
      NSError* error = nil;
      [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
      

      您的线程将阻塞,直到发出请求。

      【讨论】:

      • 同步请求会阻塞 GUI 并浪费资源。异步不允许并且允许更好的错误处理和取消。
      • 不,那是错误的。如果url 处没有任何内容,则不会阻塞:NSURLConnection 将下载 404 网页的内容。但是您可以使用[response statusCode] 查看状态码
      • @MacMark 为什么你认为同步请求会阻塞 GUI?如果我非常小心地将它放在一个不会的 NSOperation 中怎么办?在这一点上 - 回答我的问题 - 与异步请求相比,它们究竟是如何“浪费资源”的? (就此而言,它们如何允许更好的错误处理......除非您改用 NSURlConnection 协议,我认为如果您真的愿意,您仍然可以这样做,尽管它有点复杂并且如果您已经线程操作,完全适得其反,本身就是浪费资源!)
      猜你喜欢
      • 1970-01-01
      • 2011-08-24
      • 2021-07-06
      • 2019-11-27
      • 2014-08-04
      • 1970-01-01
      • 1970-01-01
      • 2010-11-25
      • 2019-01-13
      相关资源
      最近更新 更多