2015-12-02 7 views
0

У меня возникли проблемы с загрузкой видео youku.com внутри UIWebView в моем приложении. Я уверен, что это связано с безопасностью приложений App Transport, потому что замена встраивания на HTTPS-URL работает отлично. Разумеется, нет эквивалентного URL HTTPS, потому что Китай.Как отлаживать NSAllowsArbitraryLoads не работает?

Я читал о различных настройках NSAppTransportSecurity. Моим первым инстинктом, конечно, было попробовать NSAllowsArbitraryLoads, чтобы хотя бы проверить проблему, но это не сработало. Затем я последовал за различными онлайн-гидами, которые показывают, как NSExceptionDomains, как вы предполагали, но это тоже не работает.

И теперь я застрял. FWIW, я ловлю ошибки URL загрузки, как это:

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error 
{ 
    ... 
    if (error.code == NSURLErrorCancelled) 
    { 
     NSLog(@"NSURLErrorCancelled: URL %@ error %@", urlString, error); 
    } 
} 

На данный момент я использую фиктивный тест URL exon.name, и производит:

2015-12-02 15:47:22.312 ZaoMengShe[81707:903426] NSURLErrorCancelled: URL https://dev1.zaomengshe.com/c/54260 error Error Domain=NSURLErrorDomain Code=-999 "(null)" UserInfo={NSErrorFailingURLKey=http://exon.name/, NSErrorFailingURLStringKey=http://exon.name/} 

Чтобы подтвердить, -999 это ошибка, когда приложение Transport Security делает это, правильно? (Это не очень информативная ошибка!)

Другое дело, как указано в. NSAllowsArbitraryLoads not working, заключается в том, что вам нужно отредактировать файл «Info.plist». У меня нет такого файла. У меня есть «ZaoMengShe-Info.plist» («ZaoMengShe» - это имя моего приложения). Но ни один из вопросов не показывает фактический скриншот, включая имя файла, поэтому для всех я знаю, что каждый файл Info.plist фактически включает имя приложения, и это нормально. Я ошибаюсь?

App Transport Security Settings Info.plist settings

+1

код ошибки '-999' означает ошибку' kCFURLErrorCancelled'. – holex

ответ

2

Оказывается, что NSAllowsArbitraryLoads работает нормально в данном случае. Моя проблема в том, что я нажимаю другое ограничение. В новой политике безопасности вам не разрешено загружать небезопасное (HTTP) активное содержимое на защищенной (HTTPS) странице. Это верно и в браузере, и в UIWebView. Кажется, что нет никакого способа отключить это поведение.

Вот несколько дополнительных журналов, чтобы показать сообщение об ошибке с выключенным NSAllowsArbitraryLoads и затем включенным.Он не может так или иначе, но я получаю дополнительное сообщение об ошибке в первом случае:

2015-12-07 17:58:10.589 TestWeb[13583:4566542] about to load url https://dev1.zaomengshe.com/c/54260 
2015-12-07 17:58:15.966 TestWeb[13583:4569606] App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file. 
2015-12-07 17:58:16.045 TestWeb[13583:4566542] failed to load 
2015-12-07 17:58:40.879 TestWeb[13583:4566542] NSURLErrorCancelled: error Error Domain=NSURLErrorDomain Code=-999 "(null)" UserInfo={NSErrorFailingURLKey=http://exon.name/, NSErrorFailingURLStringKey=http://exon.name/} 
2015-12-07 17:58:40.895 TestWeb[13583:4569023] void SendDelegateMessage(NSInvocation *): delegate (webView:decidePolicyForNavigationAction:request:frame:decisionListener:) failed to return after waiting 10 seconds. main run loop mode: kCFRunLoopDefaultMode 
2015-12-07 17:58:41.878 TestWeb[13583:4569606] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802) 
2015-12-07 17:58:41.884 TestWeb[13583:4566542] finished load urlString: https://dev1.zaomengshe.com/c/54260 

2015-12-07 17:54:57.431 TestWeb[13503:4532874] about to load url https://dev1.zaomengshe.com/c/54260 
2015-12-07 17:55:02.339 TestWeb[13503:4532874] failed to load 
2015-12-07 17:55:15.310 TestWeb[13503:4532874] NSURLErrorCancelled: error Error Domain=NSURLErrorDomain Code=-999 "(null)" UserInfo={NSErrorFailingURLKey=http://exon.name/, NSErrorFailingURLStringKey=http://exon.name/} 
2015-12-07 17:55:15.313 TestWeb[13503:4533886] void SendDelegateMessage(NSInvocation *): delegate (webView:decidePolicyForNavigationAction:request:frame:decisionListener:) failed to return after waiting 10 seconds. main run loop mode: kCFRunLoopDefaultMode 
2015-12-07 17:55:16.210 TestWeb[13503:4534307] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9843) 
2015-12-07 17:55:16.653 TestWeb[13503:4532874] finished load urlString: https://dev1.zaomengshe.com/c/54260 

В моем случае я загружал небезопасную Youku видео в IFRAME, и плавающие фреймы рассчитывать в качестве активного содержимого. Таким образом, нет никакого способа заставить его работать. Youku не предоставляет контент HTTPS.

Решение оказывается элегантным: переместите все приложение обратно в HTTP-версию моего сайта и сохраните флаг NSAllowsArbitraryLoads. Ура! Это был забавный эксперимент с HTTPS, спасибо за это. Не забудьте вернуться ко мне, когда это сработает.

0

Пожалуйста, проверьте ваши целевые параметры. Имя вашего файла .plist должно быть в разделе «Упаковка» настроек сборки в параметре с именем Info.plist. Это должен быть относительный путь к файлу .plist из папки, содержащей файл проекта.

UPDATE: Ваше сообщение об ошибке содержит URL https://dev1.zaomengshe.com/c/54260 Если открыть этот URL из браузера вы увидите это HTTPS сертификат не является доверенным. Таким образом, отмена ваших запросов происходит не из-за безопасности приложений на транспорте, а из надежной защиты сертификатов UIWebView.

Существует одно решение для этого случая. Прежде чем UIWebView начнет загрузку запроса с ненадежного URL-адреса, вы должны доверять ему. Система загрузки URL-адресов кэширует ваши запросы. И когда вы все-таки программно скажете, что он загружается, UIWebView начинает загрузку с этого URL-адреса.

Вот фрагмент кода, я использовал в моем проекте:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{ 
    if([request.URL.scheme isEqualToString:@"https"] && ![request.URL.absoluteString hasPrefix:[AppData sharedInstance].serverBaseUrl] && ![self.authenticatedUrls containsObject:request.URL.absoluteString]){ 
     __weak NBTransferFromCardConfirmationVC * weakself = self; 
     NBInsecureSslAuth * auth=[NBInsecureSslAuth new]; 
     [auth authInsecureUrlRequet:request 
     success:^{ 
      [weakself.authenticatedUrls addObject:request.URL.absoluteString]; 
      [webView loadRequest:request]; 
     } failure:^(NSError *error) { 
      [weakself.authenticatedUrls addObject:request.URL.absoluteString]; 
      [webView loadRequest:request]; 
//   showErrorWithTitle(@"Error", error.localizedDescription); 
     }]; 
     return NO; 
    }else{ 
     return YES; 
    } 
} 

Исходный код NBInsecureSslAuth:

@implementation NBInsecureSslAuth 

- (void)authInsecureUrlRequet:(NSURLRequest*)request success:(void (^)(void))success failure:(void (^)(NSError * error))failure{ 

AFHTTPClient* client = [[AFHTTPClient alloc] initWithBaseURL:request.URL]; 

client.allowsInvalidSSLCertificate=YES; 

[client setDefaultHeader:@"User-Agent" value:[NSString stringWithFormat:@"%@/%@ (iOS %@)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleExecutableKey] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleIdentifierKey], [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleVersionKey], [[NSProcessInfo processInfo] operatingSystemVersionString]]]; 

NSMutableURLRequest * authRequest=[client requestWithMethod:request.HTTPMethod path:@"" parameters:nil]; 

AFHTTPRequestOperation * operation= 
[client HTTPRequestOperationWithRequest:authRequest 
           success:^(AFHTTPRequestOperation *operation, id responseObject) { 
            if(success){ 
             success(); 
            } 
           } 
           failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
            if(failure){ 
             failure(error); 
            } 
           }]; 

[client enqueueHTTPRequestOperation:operation]; 


} 


@end 
+0

Благодарю вас, это разъясняет! Я прикрепил скриншот, он выглядит так, как будто я все правильно настраиваю. –

+0

Хорошо, что касается плохого сертификата ... это, конечно, просто моя тестовая среда. Я уже импортировал сертификат на симулятор. Без этого я вообще не могу загружать данные. Тот факт, что он может успешно выполнить запросы AJAX после импорта сертификата, говорит о том, что это не проблема. Кроме того, эта проблема существует в живой версии нашего приложения, смотрящей на сайт, на котором есть действительный сертификат. –

+0

Пожалуйста, обратите внимание, что, разрешив ненадежным веб-сайтам, вы открываете свое приложение любому хакеру. Особенно, если вы получаете ошибки с вашего сайта _own_, тогда решение должно исправить веб-сайт, а не доверять ненадежным веб-сайтам. Любой хакер может перенаправлять запросы с вашего сайта на свой, но они не могут подделывать сертификаты. Доверяя ненадежным сайтам, им не нужно ничего подделывать. – gnasher729

 Смежные вопросы

  • Нет связанных вопросов^_^