2011-07-22 36 views
26

Chúng tôi có một ứng dụng iOS sử dụng UIWebView để hiển thị nội dung. Chúng tôi tải nó lên với dữ liệu có mã trông giống như sau:Bỏ qua Chứng chỉ Máy chủ Không hợp lệ với UIWebView

NSURL *url = [NSURL URLWithString:myURLString]; 
NSURLRequest *request = [NSURLRequest requestWithURL:url]; 
[_webView setDelegate:self]; 
[_webView loadRequest:request]; 

Điều này được sử dụng để làm việc tốt với yêu cầu HTTP, nhưng bây giờ chúng tôi đang sử dụng HTTPS đối với máy chủ có chứng chỉ SSL tự ký. Khi ở trên được điều hành, phương pháp webView:didFailLoadWithError: đại biểu được gọi là, với lỗi này:

The certificate for this server is invalid. You might be connecting to a server that is pretending to be "blah.blah.blah.com" which could put your confidential information at risk."

Tôi muốn chỉ đơn giản là bỏ qua giấy chứng nhận hợp lệ và tiếp tục với các yêu cầu, như người ta có thể làm gì trong Mobile Safari.

Tôi đã xem cách khắc phục sự cố này khi sử dụng NSURLConnection (xem HTTPS request on old iphone 3g, ví dụ), nhưng bạn có thể làm gì với số UIWebView?

Tôi tưởng tượng rằng tôi có thể làm lại mã để nó sử dụng NSURLConnection để thực hiện yêu cầu và sau đó đặt kết quả vào chế độ xem web bằng cách gọi phương thức loadHTMLString:baseURL: của chúng tôi, nhưng sẽ phức tạp hơn khi các trang có hình ảnh, CSS, JavaScript, v.v. Có cách nào dễ hơn không?

Trả lời

0

Theo như tôi biết, điều đó là không thể chỉ với UIWebView. Theo tôi hiểu điều đó, bạn cần sử dụng NSURLConnection để xử lý tất cả mojo HTTP/HTTPS và sau đó cấp kết quả của nó vào UIWebView qua -loadHtmlString:baseURL: hoặc -loadData:MIMEType:textEncodingName:baseURL:.

21

Xin lưu ý: API này hiện không được hỗ trợ và chỉ nên được sử dụng trong môi trường thử nghiệm an toàn. Để biết thêm chi tiết, hãy xem số điện thoại CocoaNetics article này.

[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[url host]]; sẽ cho phép bạn bỏ qua lỗi chứng chỉ. Bạn cũng sẽ cần phải thêm dòng sau vào đầu tập tin cấp cho bạn truy cập vào các API tin:

@interface NSURLRequest (DummyInterface) 
+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString*)host; 
+ (void)setAllowsAnyHTTPSCertificate:(BOOL)allow forHost:(NSString*)host; 
@end 
+4

Cách sử dụng cách tiếp cận này sẽ khiến ứng dụng của bạn từ chối bởi AppStore. – Franklin

+9

Thật hoàn hảo khi sử dụng chứng chỉ máy chủ lưu trữ cục bộ tự ký. Tôi bao quanh tất cả với '#if DEBUG' để không bị từ chối. – bendytree

16

Chỉ cần để mọi người đều biết ... việc sử dụng trên các giao diện ẩn SẼ KHÔNG được chấp nhận bởi APPLE. Họ tìm kiếm sử dụng các API riêng và nó KHÔNG phải là một giải pháp có thể chấp nhận được. Vì vậy, xin vui lòng không gửi bài giải pháp được mô tả ở trên như là cách để sửa chữa nó bởi vì, mặc dù nó hoạt động, nó sẽ mua cho bạn một từ chối trong AppStore. Điều đó làm cho nó vô ích.

Cách sau là phương pháp CHẤP NHẬN bỏ qua chứng chỉ máy chủ không hợp lệ. Bạn cần phải sử dụng NSURLConnection và tải các dữ liệu cho trang web bằng tay như sau:

. 
. 
. 
    //Create a URL object. 
    url = [NSURL URLWithString:urlAddress]; 
    NSURLRequest *requestObj = [NSURLRequest requestWithURL:url]; 
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:requestObj delegate:self]; 
    [connection start]; 
} 

Và sau đó, trong đại biểu của bạn ....

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace 
{ 
    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]; 
} 

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 
{ 
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) 
    { 
     [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge]; 
    } 
    else 
    { 
     [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge]; 
    } 
} 

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
{ 
[resultData appendData:data]; 
} 


- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
{ 
    NSString *htmlString = [[NSString alloc] initWithBytes:[resultData bytes] length:[resultData length] encoding:NSUTF8StringEncoding]; 
    [webView loadHTMLString:htmlString baseURL:url]; 
} 
@end 

đâu resultData là một NSMutableData bạn khởi tạo trước đó và ở đâu url và urlAddress là cả hai thứ bạn đã khởi tạo và điền vào ở nơi khác.

Thật không may, hiện tại tôi không biết cách tải UIWebView thực tế để tải trang trực tiếp mà không có chứng chỉ hợp lệ.

Yours, GC

+2

vấn đề với cách tiếp cận này là webview của bạn sẽ không hiển thị bất kỳ nội dung động nào - CSS sẽ không tải, javascript hoặc bất kỳ lệnh gọi REST được nhúng nào vv Đây là vấn đề của tôi vào lúc này. Có một cách phức tạp để làm điều đó gợi ý [ở đây] (http://stackoverflow.com/questions/11573164/uiwebview-to-view-self-signed-websites-no-private-api-not-nsurlconnection-i) – Stretch

+0

Điều này không phải là một giải pháp có thể chấp nhận được cho các trang web động chẳng hạn. có javascript phụ thuộc vào window.location sau khi chuyển hướng. Bản thân UIWebView cần quản lý vị trí của nó và xử lý các chuyển hướng, một cái gì đó không thể thực hiện được bằng cách cho nó dữ liệu từ một NSURLConnection. – davidgoli

3

Nó chỉ ra rằng một khi trang web được xác thực bởi một NSURLConnection hủy bỏ, các UIWebView có thể đưa ra yêu cầu cho trang web.There is a complete explanation here.

+0

Câu trả lời này: http://stackoverflow.com/questions/11573164/uiwebview-to-view-self-signed-websites-no-private-api-not-nsurlconnection-i/15074358#15074358 có cách thông minh về vấn đề này . – zadr

Các vấn đề liên quan