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

React Native iOS WebView加载HTTPS证书无效问题咨询

Fixing iOS React Native WebView -1202 Certificate Error

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:

  1. Add the Certificate to Your Project: Drag your .cer format certificate into your iOS project, making sure to check "Add to targets" for your main app.
  2. Configure ATS Exceptions: Update Info.plist with these settings (again, replace example.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>
  1. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:58:11