iOS webview无法加载网页Domain=NSURLErrorDomain Code=-1202

本文介绍了解决HTTPS证书错误的方法,包括使用AFNetworking时如何配置安全策略以允许无效证书,并提供了UIWebView中处理证书验证问题的示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

错误

在应用中由 http转为 https 时, 报错了, 下面是错误:
NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)或者
Error Domain=NSURLErrorDomain Code=-1202 “The certificate for this server is invalid. “

原因

这是由于你的 https的证书失效, 或者是自建证书, 你需要跳过验证, 允许其进行服务器的连接.

请求错误中的解决方案

1.一般的,如果用的 AFN 的话你可以加上以下代码:

AFSecurityPolicy * securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
//allowInvalidCertificates 是否允许无效证书(也就是自建的证书),默认为NO
//如果是需要验证自建证书,需要设置为YES
securityPolicy.allowInvalidCertificates = YES;
//validatesDomainName 是否需要验证域名,默认为YES;
//假如证书的域名与你请求的域名不一致,需把该项设置为NO
//主要用于这种情况:客户端请求的是子域名,而证书上的是另外一个域名。因为SSL证书上的域名是独立的,假如证书上注册的域名是www.google.com,那么mail.google.com是无法验证通过的;当然,有钱可以注册通配符的域名*.google.com,但这个还是比较贵的。
securityPolicy.validatesDomainName = NO;
//validatesCertificateChain 是否验证整个证书链,默认为YES
//设置为YES,会将服务器返回的Trust Object上的证书链与本地导入的证书进行对比,这就意味着,假如你的证书链是这样的:
//GeoTrust Global CA 
//    Google Internet Authority G2
//        *.google.com
//那么,除了导入*.google.com之外,还需要导入证书链上所有的CA证书(GeoTrust Global CA, Google Internet Authority G2);
//如是自建证书的时候,可以设置为YES,增强安全性;假如是信任的CA所签发的证书,则建议关闭该验证;
securityPolicy.validatesCertificateChain = NO;
requestOperationManager.securityPolicy = securityPolicy;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

2.若还是不可进行请求, 你可以尝试在你的请求类中加入以下代码:

- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * __nullable credential))completionHandler{
    NSLog(@"didReceiveChallenge");
//    if([challenge.protectionSpace.host isEqualToString:@"api.lz517.me"] /*check if this is host you trust: */ ){
    completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
//    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

3.加入代码后本人遇到的问题就解决了, 但是如果你的请求还有问题你可以参考以下,
这里写图片描述
和这个问题 http://stackoverflow.com/questions/33827351/how-to-solve-this-nsurlsession-nsurlconnection-http-load-failed-kcfstreamerrord

这里也重点推荐一篇文章是关于 ATS 的: App Transport Security(ATS)
https自建证书在 AFN中的设置
网络请求及各类错误代码含义总结

UIWebView中解决方案实例:

#import "LoginProTocalVC.h"

@interface LoginProTocalVC (){
    NSURLConnection *_urlConnection;
    NSURLRequest *_request;
    BOOL _authenticated;
    UIWebView *webV;
}

@end

@implementation LoginProTocalVC

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self configNavigationBar];
    [self configBody];
    // Do any additional setup after loading the view.
}
- (void)configBody{
    
   webV = [[UIWebView alloc]initWithFrame:CGRectMake(0, 64, self.view.frame.size.width, self.view.frame.size.height-64)];
    [self.view addSubview:webV];
    
//    if (currentType == YBNetworkTest) {
//        [view loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://services.xxx.com/newsdetail/4"]]];
//    }else if(currentType == YBNetworkT1Service){
//        [view loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://t1services.xx.com/newsdetail/4"]]];
//    }else if (currentType == YBNetworkDistribution){
//        [view loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://appservices.xxx.com/newsdetail/4"]]];
//    }else if (currentType == YBNetworkApp1Service){
//        [view loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://app1services.xxx.com/newsdetail/4"]]];
//    }
    NSString *urlStr = @"";
    if (currentType == YBNetworkTest) {
        urlStr = @"https://www.xxx.com/newsdetail/4";
    }else if(currentType == YBNetworkT1Service){
        urlStr = @"https://www.xxx.com/newsdetail/4";
    }else if (currentType == YBNetworkDistribution){
        urlStr = @"https://www.xxx.com/newsdetail/4";
    }else if (currentType == YBNetworkApp1Service){
        urlStr = @"https://www.xxx.com/newsdetail/4";
    }
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlStr]];
    
    webV.delegate = self;
    [webV loadRequest:request];
}
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    
    NSLog(@"Did start loading: %@ auth:%d", [[request URL]absoluteString],_authenticated);
    if (!_authenticated) {
        _authenticated = NO;
        _request = request;
        _urlConnection = [[NSURLConnection alloc] initWithRequest:_request delegate:self];
        [_urlConnection start];
        return NO;
    }
    return YES;
}
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
    NSLog(@"WebController Got auth challange via NSURLConnection");
    if ([challenge previousFailureCount] == 0) {
        _authenticated = YES;
        NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
        [challenge.sender useCredential:credential forAuthenticationChallenge:challenge];
    }else{
        [[challenge sender] cancelAuthenticationChallenge:challenge];
    }
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    NSLog(@"WebController received response via NSURLConnection");
    // remake a webview call now that authentication has passed ok.
    _authenticated = YES;
    [webV loadRequest:_request];
    
    // Cancel the URL connection otherwise we double up (webview + url connection, same url = no good!)
    [_urlConnection cancel];
}
-(void)configNavigationBar{
    //创建颜色背景View
    UIView *bgView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 64)];
    bgView.backgroundColor = [UIColor whiteColor];
    //     bgView.backgroundColor = [UIColor lightGrayColor];
    bgView.clipsToBounds = YES;
    [self.view addSubview:bgView];
    //创建返回按钮
    UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    backBtn.frame = CGRectMake(5 , 20, 40, 40);
    [backBtn setImage:[UIImage imageNamed:@"regist_vc1_nv_back"] forState:UIControlStateNormal];
    
    [backBtn addTarget:self action:@selector(backBtnClick) forControlEvents:UIControlEventTouchUpInside];
    [bgView addSubview:backBtn];
    
    UILabel *titltlabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 20, bgView.frame.size.width, 40)];
    titltlabel.textAlignment = NSTextAlignmentCenter;
    titltlabel.textColor = [UIColor blackColor];
    titltlabel.text = @"用户协议";
    //    titltlabel.font = [UIFont systemFontOfSize:15];
    titltlabel.font = kYBTitleFont;
    [bgView addSubview:titltlabel];
    
    
    UIImageView *lingImg = [[UIImageView alloc] initWithFrame:CGRectMake(0, bgView.frame.size.height-0.5, bgView.frame.size.width, 0.5)];
    lingImg.backgroundColor = [UIColor lightGrayColor];
    [bgView addSubview:lingImg];
    
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
 #pragma mark - Navigation
 
 // In a storyboard-based application, you will often want to do a little preparation before navigation
 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
 // Get the new view controller using [segue destinationViewController].
 // Pass the selected object to the new view controller.
 }
 */


- (void)backBtnClick {
    
    //zyp
    NSArray *viewcontrollers=self.navigationController.viewControllers;
    if (viewcontrollers.count>1) {
        if ([viewcontrollers objectAtIndex:viewcontrollers.count-1]==self) {
            //push方式
            [self.navigationController popViewControllerAnimated:YES];
        }
    }
    else{
        //present方式
        [self dismissViewControllerAnimated:YES completion:nil];
    }
    
    //end
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end




<think>首先,用户的问题是关于在UniApp中向WebView组件传递参数的方法。用户说:“我想在UniApp中向WebView组件传递参数的方法 请问uniapp webview 传递参数 方法 实现方式”。我需要基于提供的引用信息来回答。 回顾引用内容: - 引用[1]:描述了使用`plus.webview.create`创建WebView并传递参数,通过`data`对象传递参数。还提到了使用`uni.postMessage()`回传参数。 - 引用[2]:讨论了在WebView页面接收参数的事件,如`message`事件,以及在WebView页面发送参数回应用的方法,如`uni.webView.postMessage`。 - 引用[3]:提到在H5端直接解析URL参数。 用户的问题聚焦在传递参数给WebView组件,所以我应该覆盖主要的实现方式。 关键点: 1. **传递参数到WebView**:可以通过URL查询参数或通过`data`对象在创建WebView时传递。 2. **在WebView中接收参数**:在H5页面中,可以通过解析URL参数或监听事件来接收。 3. **回传参数**:WebView页面可以使用`uni.webView.postMessage`发送消息回UniApp应用。 回答结构需要清晰、逐步解决问题。系统指令要求: - 使用中文回答。 - 行内数学表达式用`$...$`,但我这里没有数学表达式,所以可能不需要。 - 独立公式用`$$...$$`,但同样,没有数学内容。 - LaTeX语法正确:确保代码块正确。 - 生成相关问题:在回答末尾添加相关问题。 - 添加引用标识:在引用的段落末尾自然地添加,如[^1]。 组织回答: 1. **介绍方法**:简要概述传递参数的常见方式。 2. **详细步骤**:分步解释如何实现。 - 方法1:通过URL传递参数(简单,但可能暴露敏感信息)。 - 方法2:通过`data`对象在创建WebView时传递(更安全,引用[1])。 - 接收参数在H5端:如何解析URL或使用事件监听。 - 回传参数:如何从H5发送消息回UniApp(引用[2])。 3. **代码示例**:提供代码片段来演示。 4. **注意事项**:提到安全性和兼容性。 5. **相关问题**:在末尾生成相关问题。 确保回答真实可靠,基于提供的引用。 最终回答结构: - 标题:UniApp中向WebView传递参数的方法 - 正文:分点解释。 - 代码块:使用正确的格式。 - 结尾:相关问题。 相关问题建议: 1. 如何在UniApp中从WebView接收回传参数? 2. UniApp WebView参数传递的最佳实践是什么? 3. 如何处理WebView参数传递中的安全问题? 现在,草拟回答。</think>### UniApp中向WebView传递参数的方法 在UniApp中向WebView组件传递参数,主要有两种常用方法:通过URL查询参数传递,或通过`data`对象在创建WebView时传递。这两种方式各有适用场景,且需结合H5端的参数接收机制。以下我将基于UniApp官方文档和实际开发经验,逐步解释实现步骤,确保方法可靠且易于集成。引用信息来自可靠的UniApp社区和开发指南[^1][^2][^3]。 #### 方法1: 通过URL查询参数传递(简单直接) 此方法适合传递少量、非敏感参数(如ID或状态标识),直接在WebView的URL中添加查询字符串。H5端通过解析URL获取参数。 - **实现步骤**: 1. **UniApp端设置URL**:在创建WebView时,将参数拼接在URL中。例如: ```javascript // 在UniApp页面中创建WebView let token = &#39;user_token_123&#39;; let userId = &#39;1001&#39;; let url = `https://your-h5-domain.com/page?token=${token}&userId=${userId}`; // 添加查询参数 let wv = plus.webview.create( url, // URL包含参数 &#39;webview_id&#39;, { top: &#39;0&#39;, height: &#39;100%&#39;, width: &#39;100%&#39; } ); let currentWebview = this.$scope.$getAppWebview(); // 获取当前Webview对象 currentWebview.append(wv); // 添加WebView到页面 ``` 2. **H5端接收参数**:在H5页面中,使用JavaScript解析URL的查询字符串。例如: ```javascript // 在H5页面的onLoad或mounted中 const queryParams = new URLSearchParams(window.location.search); const token = queryParams.get(&#39;token&#39;); // 获取token参数 const userId = queryParams.get(&#39;userId&#39;); console.log(token, userId); // 输出参数值 ``` - **优点**:实现简单,兼容性好。 - **缺点**:参数暴露在URL中,不适合传递敏感数据(如用户凭证)[^3]。 #### 方法2: 通过`data`对象传递(推荐,更安全) 此方法使用`plus.webview.create`的`extras`选项传递参数对象,避免URL暴露。H5端需通过事件监听接收参数,适合传递复杂或敏感数据(如JSON对象)。 - **实现步骤**: 1. **UniApp端创建WebView并传递`data`对象**:在`extras`中定义`data`键值对,确保参数以对象形式传递。 ```javascript // UniApp页面中 let token = &#39;user_token_123&#39;; let userInfo = { name: &#39;张三&#39;, role: &#39;admin&#39; }; let wv = plus.webview.create( &#39;https://your-h5-domain.com/page&#39;, // URL无需参数 &#39;webview_id&#39;, { top: &#39;0&#39;, height: &#39;100%&#39;, width: &#39;100%&#39; }, { data: { token, userInfo, implantType: &#39;uniapp&#39; } } // 通过data对象传递 ); let currentWebview = this.$scope.$getAppWebview(); currentWebview.append(wv); // 关键:必须添加,否则WebView不生效 ``` - 注意:使用`data`键值对确保参数以单一对象传递,避免H5端解析混乱[^1]。 2. **H5端接收参数**:需在H5页面中监听`UniAppJSBridgeReady`事件,并使用`uni.getEnv`获取参数。 - 首先,确保H5页面引入UniApp的WebView SDK(如`uni.webview.js`): ```html <!-- 在H5页面的head中引入SDK --> <script src="https://gitcode.net/dcloud/uni-app/-/raw/dev/dist/uni.webview.1.5.4.js"></script> ``` - 然后在JavaScript中监听事件并获取参数: ```javascript // H5页面脚本 document.addEventListener(&#39;UniAppJSBridgeReady&#39;, () => { uni.getEnv((env) => { if (env.plus) { const appParams = plus.webview.currentWebview().data; // 直接获取data对象 console.log(appParams.token, appParams.userInfo); // 输出参数 } }); }); ``` - **优点**:参数封装在对象中,安全性更高,支持复杂数据结构。 - **缺点**:需依赖UniApp SDK,增加H5端复杂度[^1][^2]。 #### 参数回传(WebView向UniApp发送数据) 如果需要从H5页面回传参数到UniApp,可使用`uni.webView.postMessage`方法: - **H5端发送消息**: ```javascript // 在H5页面中,例如按钮点击事件 document.getElementById(&#39;submit-btn&#39;).addEventListener(&#39;click&#39;, () => { uni.webView.postMessage({ data: { action: &#39;submit&#39;, formData: { name: &#39;李四&#39;, age: 30 } } // 回传参数对象 }); }); ``` - **UniApp端接收消息**:在WebView组件的`@message`事件中处理。 ```html <!-- UniApp页面模板 --> <web-view :src="webviewUrl" @message="handleMessage"></web-view> ``` ```javascript // UniApp脚本 methods: { handleMessage(event) { const params = event.detail.data; // 获取回传参数 console.log(params.action, params.formData); // 输出: &#39;submit&#39;, { name: &#39;李四&#39;, age: 30 } } } ``` - 注意:在页面卸载时移除监听器以避免内存泄漏[^2]。 #### 注意事项 - **安全性**:避免通过URL传递敏感数据;优先使用`data`对象并结合HTTPS。 - **兼容性**:测试不同平台(iOS/Android),确保`plus.webview` API在真机生效。 - **性能**:大量参数时,`data`对象比URL更高效。 - **调试**:使用`console.log`或UniApp开发者工具检查参数传递。 通过以上方法,您可灵活实现参数传递。如需完整示例代码,可参考UniApp官方GitHub仓库或社区文档[^1][^2][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值