React Native iOS WebView加载HTTPS证书无效问题咨询
That -1202 error boils down to iOS rejecting the SSL certificate for your target site. Safari lets users manually trust invalid/self-signed certificates, but React Native's WebView sticks strictly to system security rules and won't show that trust prompt—hence the failure. Let's break down solutions for both development and production scenarios:
1. Temporary Workaround for Development (DO NOT use in production)
If you just need to bypass validation for local testing, here are two quick options:
Option 1: Add ATS Exceptions in Info.plist
Open your iOS project's Info.plist and add this configuration (replace example.com with your domain):
<key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <key>example.com</key> <dict> <key>NSExceptionAllowsInsecureHTTPLoads</key> <true/> <key>NSExceptionRequiresForwardSecrecy</key> <false/> <key>NSIncludesSubdomains</key> <true/> </dict> </dict> </dict>
This loosens security for that specific domain to allow invalid certificates, but never ship this in a production build—Apple will reject your app from the App Store.
Option 2: Disable Certificate Validation via Native Code (WKWebView)
If you're using WKWebView (the default for RN WebView, or set useWebKit={true}), add this code to your AppDelegate.m to globally skip certificate checks (wrapped in a debug guard):
#import <WebKit/WebKit.h> @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Your existing code here... #ifdef DEBUG // Swizzle WKWebView init to use a custom URLSession that skips cert checks Class wkWebViewClass = NSClassFromString(@"WKWebView"); SEL originalInit = @selector(initWithFrame:configuration:); SEL swizzledInit = @selector(swizzled_initWithFrame:configuration:); Method originalMethod = class_getInstanceMethod(wkWebViewClass, originalInit); Method swizzledMethod = class_getInstanceMethod([self class], swizzledInit); if (class_addMethod(wkWebViewClass, originalInit, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))) { class_replaceMethod(wkWebViewClass, swizzledInit, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); } else { method_exchangeImplementations(originalMethod, swizzledMethod); } #endif return YES; } - (instancetype)swizzled_initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration { NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:nil]; configuration.URLSession = session; return [self swizzled_initWithFrame:frame configuration:configuration]; } #pragma mark - NSURLSessionDelegate - (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler { if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; completionHandler(NSURLSessionAuthChallengeUseCredential, credential); return; } completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil); } @end
The #ifdef DEBUG ensures this only runs in development builds, keeping your production code safe.
2. Production-Ready Solutions
For apps going to the App Store or enterprise distribution, you need a compliant approach to get iOS to trust the certificate:
Option 1: Use a Publicly Trusted CA Certificate
The simplest and most reliable fix is to have your server switch to an SSL certificate issued by a public trusted CA (like Let's Encrypt, DigiCert, or GlobalSign). iOS automatically trusts these certificates, so no extra configuration is needed for WebView to load the site.
Option 2: Trust a Self-Signed Certificate (Internal/Enterprise Apps Only)
If you're using a self-signed certificate for internal use, follow these steps to make your app trust it:
- Add the Certificate to Your Project: Drag your
.cerformat certificate into your iOS project, making sure to check "Add to targets" for your main app. - Configure ATS Exceptions: Update
Info.plistwith these settings (again, replaceexample.com):
<key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <key>example.com</key> <dict> <key>NSExceptionRequiresForwardSecrecy</key> <false/> <key>NSIncludesSubdomains</key> <true/> <key>NSExceptionMinimumTLSVersion</key> <string>TLSv1.2</string> </dict> </dict> </dict>
- Validate and Trust the Certificate in Code: Implement WKWebView's navigation delegate to compare the server's certificate with your local one:
// In your custom WKNavigationDelegate class - (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler { if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { SecTrustRef serverTrust = challenge.protectionSpace.serverTrust; SecCertificateRef serverCert = SecTrustGetCertificateAtIndex(serverTrust, 0); // Load your local certificate NSString *localCertPath = [[NSBundle mainBundle] pathForResource:@"your-cert-filename" ofType:@"cer"]; NSData *localCertData = [NSData dataWithContentsOfFile:localCertPath]; SecCertificateRef localCert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)localCertData); // Compare server cert with local cert if (SecCertificateCompare(serverCert, localCert) == kCFCompareEqualTo) { NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust]; completionHandler(NSURLSessionAuthChallengeUseCredential, credential); } else { completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil); } CFRelease(localCert); } else { completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil); } }
Then, link this delegate to your RN WebView (either via a custom native wrapper or by accessing the WebView's ref and setting the delegate in native code).
内容的提问来源于stack exchange,提问作者Sport

