WKWebView和UIWebView

iOS UIWebView和WKWebView的JS调用详解 一般应用开发,用到webview和JS交互的地方特别多,当然也有很多优秀的第三方可以使用,例如:WebViewJavascriptBridge,有兴趣的可以研究下,非常好用的一个框架,本文主要概括下苹果提供的原声控件和JS互相简单调用。webview以及WKWebView。      iOS8.0之前,苹果只提供UIwebview一个控件,这个控件JS调用OC主要通过UIwebview的代理方法 阅读详情

UIWebView自iOS2就有,WKWebView从iOS8才有,毫无疑问WKWebView将逐步取代笨重的UIWebView。通过简单的测试即可发现UIWebView占用过多内存,且内存峰值更是夸张。WKWebView网页加载速度也有提升,但是并不像内存那样提升那么多

基本属性:网页加载进度、网页标题,这些网页的最最基本的属性,终于齐了。

前进后退手势:在UIWebView实现过这个功能的我,深知此功能之复杂,当看到这个的时候,整个人都鸟肌了。
WKPreferences:对应WebView的WebViewPreference,相比UIWebView,增加了禁用JavaScript功能,但没有无图模式,差评。
WKUserContentController:JS通讯相关,App注入JS时,可以指定时机(加载开始或加载结束)和范围(MainFrame或所有Frame);另外内置JS Bridge。
WKProcessPool:和多进程模型相关,目前功能未知。
WKBackForwardList:前进后退列表,良心好评。
WKNavigationDelegate:类似于WebView里的WebFrameLoadDelegate,功能稍稍阉割了下,但基本能用。
WKUIDelegate:UI相关的回调。如新窗口打开、页面alert弹框等的处理回调。
更多细节,可以查看WebKit Objective-C Framework Reference。

UIProgressView *progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];

    [self.view addSubview:progressView];

    self.progressView = progressView;

    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
    //偏好设置
    config.preferences = [[WKPreferences alloc] init];

    config.preferences.minimumFontSize = 10;

    config.preferences.javaScriptEnabled = YES;
    //表示不能自动打开窗口
    config.preferences.javaScriptCanOpenWindowsAutomatically = NO;

    //web内容处理池,由于没有属性可以设置,也没有方法可以调用,不用手动创建
    config.processPool = [[WKProcessPool alloc] init];


    WKWebView *web2 = [[WKWebView alloc] init];//WithFrame:self.view.bounds configuration:config]; //WithFrame:self.view.bounds

    web2.navigationDelegate = self;
//    web2.UIDelegate = self;

    [web2 addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:NULL];

    [self.view addSubview:web2];
    self.web2 = web2;



    [web2.configuration.userContentController addScriptMessageHandler:self name:@"closeMe"];


    [progressView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.left.right.equalTo(self.view);

    }];

    [web2 mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(progressView.mas_bottom);
        make.left.right.bottom.equalTo(self.view);
    }];
#define mark  设置加载进度条
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{

    if ([keyPath isEqualToString:@"estimatedProgress"] && object == self.web2) {

        self.progressView.alpha = 1.0;
        [self.progressView setProgress:self.web2.estimatedProgress animated:YES];

        if (self.web2.estimatedProgress >= 1.0) {
            [UIView animateWithDuration:0.3 delay:0.3 options:UIViewAnimationOptionCurveEaseOut animations:^{
                self.progressView.alpha = 0.0;
            } completion:^(BOOL finished) {
                [self.progressView setProgress:0.0f animated:YES];
            }];

        }

    }else{
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }

}


 #pragma mark WKNavigationDelegate
 //2.页面开始加载
 - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
 NSLog(@"%s",__func__);
 }
 ///5.页面跳转完成之后调用
 - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
 NSLog(@"%s",__func__);
 }

 - (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error{
     NSLog(@"%s----%@",__func__,error);
 }
//证书设置
// 这与用于授权验证的API,与AFN、UIWebView的授权验证API是一样的
 - (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler{

     NSLog(@"%s",__func__);
//     NSString *hostName = webView.URL.host;
//     
//     NSString *authenticationMethod = [[challenge protectionSpace] authenticationMethod];
//     if ([authenticationMethod isEqualToString:NSURLAuthenticationMethodDefault]
//         || [authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPBasic]
//         || [authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPDigest]) {
//         
//         NSString *title = @"Authentication Challenge";
//         NSString *message = [NSString stringWithFormat:@"%@ requires user name and password", hostName];
//         UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
//         [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {
//             textField.placeholder = @"User";
//             //textField.secureTextEntry = YES;
//         }];
//         [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {
//             textField.placeholder = @"Password";
//             textField.secureTextEntry = YES;
//         }];
//         [alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
//             
//             NSString *userName = ((UITextField *)alertController.textFields[0]).text;
//             NSString *password = ((UITextField *)alertController.textFields[1]).text;
//             
//             NSURLCredential *credential = [[NSURLCredential alloc] initWithUser:userName password:password persistence:NSURLCredentialPersistenceNone];
//             
//             completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
//             
//         }]];
//         [alertController addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
//             completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
//         }]];
//         dispatch_async(dispatch_get_main_queue(), ^{
//             [self presentViewController:alertController animated:YES completion:^{}];
//         });
//         
//     }
//     else if ([authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
//         // needs this handling on iOS 9
//         completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
//         // or, see also http://qiita.com/niwatako/items/9ae602cb173625b4530a#%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%82%B3%E3%83%BC%E3%83%89
//     }
//     else {
//         completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
//     }

     NSURLProtectionSpace *protectionSpace = [challenge protectionSpace];

     id<NSURLAuthenticationChallengeSender> sender = [challenge sender];

     if ([[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust])
     {
         SecTrustRef trust = [[challenge protectionSpace] serverTrust];

         NSURLCredential *credential = [[NSURLCredential alloc] initWithTrust:trust];

//         [sender useCredential:credential forAuthenticationChallenge:challenge];
         completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, credential);
     }
     else
     {
//         [sender performDefaultHandlingForAuthenticationChallenge:challenge];
         completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
     }

 }


 // *  在收到响应后,决定是否跳转
 // *
 // *  @param webView            实现该代理的webview
 // *  @param navigationResponse 当前navigation
 // *  @param decisionHandler    是否跳转block

 - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {

     decisionHandler(WKNavigationResponsePolicyAllow);
 }

  // 在收到服务器的响应头,根据response相关信息,决定是否跳转。decisionHandler必须调用,来决定是否跳转,参数WKNavigationActionPolicyCancel取消跳转,WKNavigationActionPolicyAllow允许跳转
 ////1.
 // *  在发送请求之前,决定是否跳转
 // *
 // *  @param webView          实现该代理的webview
 // *  @param navigationAction 当前navigation
 // *  @param decisionHandler  是否调转block

 - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
 NSLog(@"%s",__func__);


     decisionHandler(WKNavigationActionPolicyAllow);
 }
 //4.开始获取页面内容时返回
 - (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation{

 NSLog(@"%s",__func__);
 }
 //页面跳转失败
 - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error{
     NSLog(@"%s---=====%@",__func__,error);
 }

 #pragma mark WKScriptMessageHandler{

 - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{

        NSLog(@"名称%@ --方法%@",message.name,message.body);

 }


- (void)dealloc{

    if ([self isViewLoaded]) {
        [self.web2 removeObserver:self forKeyPath:@"estimatedProgress"];
    }

    self.web2.navigationDelegate = nil;
    self.web2.UIDelegate = nil;

}

#pragma mark UIWebViewDelegate
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
    NSLog(@"%s,-----%@",__func__,request.URL.absoluteString);

    NSLog(@"Did start loading: %@ auth:%d", [[request URL] absoluteString], _authenticated);

    if (!_authenticated) {

        _authenticated = NO;

        _urlConnection = [[NSURLConnection alloc] initWithRequest:_requset delegate:self];

        [_urlConnection start];

        return NO;
    }

    return YES;
}




- (void)webViewDidStartLoad:(UIWebView *)webView{
    NSLog(@"%s",__func__);
    [UMProgressHUD show];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView{
    NSLog(@"%s",__func__);
    [UMProgressHUD dismiss];
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{
    NSLog(@"%@",error);
    [UMProgressHUD dismiss];
}

//通过connection来设置证书

#pragma mark - NURLConnection delegate

- (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];
    }
}

// We use this method is to accept an untrusted site which unfortunately we need to do, as our PVM servers are self signed.
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}



#pragma mark - NSURLConnectionDataDelegate

- (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;
    [_web1 loadRequest:_requset];

    // Cancel the URL connection otherwise we double up (webview + url connection, same url = no good!)
    [_urlConnection cancel];
}

总的来说,苹果鼓起勇气,第一次开放了如此多的接口,但却仍然不够彻底。这些功能,在UIWebView时代,都可以用私有API解决;而使用了WKWebView之后,在某些方面,依然显得不够用的样子——比方说HTTP和HTTPS验证,仍然没有公开接口可以处理;另外WebResourceLoadDelegate的缺失,也是一大痛点。

2014.7.8 iOS8 beta3 更新Webkit.framework,如下:

同步调用的JS接口。和-[UIWebView stringByEvaluatingJavaScriptFromString:]相比,JS结果是异步而非同步返回的,返回结果为id而非NSString。
WKNavigationDelegate增加了验证回调接口,可以解决HTTP和HTTPS验证问题

WkWebView和UIWebView及底层实现 背景: UIWebView是在iOS2推出的,在iOS8之后,使用WKWebView来取代UIWebView。因为UIWebView加载速度慢,占用内存多,优化困难,所以iOS8以后,苹果推出了新框架Webkit,提供了组件WKWebView。 注意:WKWebView在ios8系统上,JS进行post请求有数据不正确的问题,所以从ios9开始使用WKWebView(静等ios8以下系统被淘汰) ##UIWebView 一、初始化与三种加载方式 UIWebView继承于UIView,因此,其初始化方法和一般 阅读详情

相关推荐

MATLAB新手必看:Stewart平台运动学逆解从入门到实战(附完整代码)

本文详细介绍了如何使用MATLAB实现Stewart平台的运动学逆解,从基础原理到完整代码实现,涵盖并联机器人的数学建模、MATLAB编程和Simulink集成。通过实战案例和可视化分析,帮助新手快速掌握Stewart平台的运动学逆解技术,适用于机器人学和控制理论领域的研究与应用。

dream的博客 551

WebView 和 WKWebView的对比

网址:http://www.jianshu.com/p/403853b63537

Que_Li的博客 1009

h5页面调用微信JS-SDK分享到微信好友或者朋友圈的配置

1.引入js &lt;script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"&gt;&lt;/script&gt; 2.在页面添加配置 &lt;script type="text/javascript"&gt; var url = location.href..

tiantiandashi的博客 2万+

对于UIWebView与WKWebview的理解

iOS有UIWebview和WKWebview两种webview。从iOS13开始苹果将UIWebview列为过期API。2020年4月起App Store将不再接受使用UIWebView的新App上架、2020年12月起将不再接受使用UIWebView的App更新。 在进行5+app开发中,从HBuilderX 2.2.5起,iOS上默认均已经是WKWebview,除非开发者手动在代码中指定要用UIWebview,否则实际渲染的页面都是在WKWebview里渲染的。不过,虽然实际页面是WKWebview

cug-jdc的博客 4256

瑞芯微RK3576上手实测:8nm新U配6TOPS NPU,做AIoT项目选它还是RK3588/RK3568?

本文深度评测瑞芯微RK3576芯片在中高端AIoT项目中的表现,对比RK3588和RK3568的性能差异。RK3576采用8nm工艺,配备6TOPS NPU,在解码能力、AI推理效率和功耗控制方面表现均衡,是中端项目的黄金选择。实测数据显示其在多路视频解码和AI加速性能上优势明显,特别适合智能摄像头和工业HMI设备。

weixin_42627853的博客 716

高通平台开发系列讲解(系统篇)系统关机流程

📢本篇章主要图解高通平台系统关机流程。

内核笔记 3212

iOS UIWebView与WKWebView

第一章 - 引言在iOS开发中,WebView是一种常见的控件,用于在应用中显示网页内容。在过去,我们主要使用UIWebView作为WebView控件,但自iOS 8起,苹果推出了WKWebView,作为UIWebView的升级版本。本文将介绍UIWebView和WKWebView的特点、使用方法和案例。

good7ob的博客 1727

STM32实战开发(150):基于STM32的智能电力负荷控制系统开发

本文介绍了基于STM32的智能电力负荷控制系统的设计与实现,涵盖了硬件设计、软件设计、负荷预测与控制等多个方面。该系统能够实时监控电力负荷,预测未来负荷变化,并根据预测结果自动调节电力负荷,防止电网过载或浪费。未来,我们可以进一步优化该系统,加入更多的传感器数据,提升预测算法的精度,并结合大数据与云计算技术实现更为强大的远程控制与数据分析功能。

2201_76125393的博客 712

UIWebView和WKWebView

UIWebView 什么是UIWebView UIWebView是iOS内置的浏览器控件 系统自带的Safari浏览器就是通过UIWebView实现的 UIWebView不但能加载远程的网页资源,还能加载绝大部分的常见文件 html\htm pdf、doc、ppt、txt mp4 … … U...

weixin_42433480的博客 848

搭建自己的MQTT服务器,实现设备上云(Ubuntu+EMQX)

这篇文章教大家在ECS云服务器上部署EMQX,搭建自己私有的MQTT服务器,配置EMQX实现设备上云,设备数据转发,存储;服务器我采用的华为云的ECS服务器,系统选择Ubuntu系统。

2万+

STM32H750VB与AD5292通讯,写入阻值后,AD5292 的阻值没有变化,如何解决?

🏆 本文收录于《全栈Bug调优(实战版)》专栏,致力于分享我在项目实战过程中遇到的各类Bug及其原因,并提供切实有效的解决方案。无论你是初学者还是经验丰富的开发者,本文将为你指引出一条更高效的Bug修复之路,助你早日登顶,迈向财富自由的梦想🚀!同时,欢迎大家关注、收藏、订阅本专栏,更多精彩内容正在持续更新中。让我们一起进步,Up!Up!Up!    备注: 部分问题/难题源自互联网,经过精心筛选和整理,结合数位十多年大厂实战经验资深大佬经验总结所得,数条可行方案供所需之人参考。

**My Coding Family** 1097

UIWebView和WKWebView的对比

1.UIWebView和WKWebView UIWebView 1)UIWebView是iOS2就有了的,占用内存也比较多,内存峰值也挺夸张的 2)UIWebView继承自UIView 是用来加载网页的类,可以简单理解成就是一个view WKWebView 1)相比UIWebView的话,支持更多的HTML5的特性 2)滚动刷新率在60fps以及内置手势 3)添加了加载进度属性:es...

zxc8890304的博客 1847

Simulink仿真入门到精通(三) Simulink信号

本系列教程是根据孙忠潇编著的<<Simulink仿真及代码生成技术入门到精通>>学习笔记。 目录 Simulink仿真入门到精通(一) Simulink界面介绍 Simulink仿真入门到精通(二) Simulink模块 Simulink仿真入门到精通(三) Simulink信号 Simulink仿真入门到精通(四) Simulink子系统 Simulink仿真入门到精通(五) Simulink模型的仿真 Simulink仿真入门到精通(六) Simulink模型保存为图片 Sim

king110108的专栏 5395

UIWEBVIEW和WKWebView学习

UIWebViewDelegateUIWebViewNavigationType{ UIWebViewNavigationTypeLinkClicked,点击链接 UIWebViewNavigationTypeFormSubmitted,提交表单 UIWebViewNavigationTypeBackForward,点击前进或返回按钮 UIWebViewNavigationTypeReload,点击

no pain !no gain ! 425

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

UIWebview和WKWebview加载本地html

情况一 html文件不在文件夹里   NSURL *url = [[NSBundle mainBundle] URLForResource:@"test" withExtension:@"html"];         NSURLRequest *request = [NSURLRequest requestWithURL:url];      

flg1554112450的博客 2160

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

JS和UIWebview以及WKWebView的交互

最近做了几个hybrid的应用,有一些JS和Webview的交互经验得总结下: 看了很多大框架源码,无论是cordova还是WebViewJavascriptBridge他们核心的通信方式就都是 假跳转请求拦截   下面我们就慢慢分析: 一、WebViewJavascriptBridge分析 1,首先讲讲为什么需要WebViewJavascriptBridge: WebViewJava...

xiaoyu的博客 973

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Swift UIWebView 和 WKWebView

参考http://blog.youkuaiyun.com/zhaoweixing1989/article/details/13021513 (1)获取加载页面的Url地址,加载开始,加载完成,加载失败的监听 让当前的ViewController实现UIWebViewDelegate代理 然后实现代理中的方法:  //使用UIWebView代理方法 func webView(webVie

程序员 2200

浅谈iOS中WKWebView和UIWebView的清除缓存问题

最近产品经理在验收项目,在验收过程中发现了一个问题:网页中的数据存在缓存。 网页中加载的是一张图片,在后台将加载的图片换掉的时候再在App中加载此网页,发现展示的图片还是之前的图片,并没有更新,而且多次重新加载网页显示的还是之前的图片,说明缓存很严重。于是查阅资料进行缓存的清除。 先说说UIWebView中缓存的清除,代码只有一句:  [[NSURLCache sharedURLC

梁森的博客 1万+

UIWebView和WKWebView的使用及js交互

UIWebView和WKWebView的使用及js交互 web页面和app直接的交互是很常见的东西,之前尝试过flex和js的相互调用以及android和js的相互调用,却只有ios没试过,据说比较复杂。周末花了点时间研究了一下,确实和其他的不太一样,但是 也不见复杂。 要知...

chuanao8829的博客 196

iOS H5容器的一些探究:UIWebView和WKWebView的比较和选择

iOS H5容器的一些探究:UIWebView和WKWebView的比较和选择

u012371575的博客 793

iOS 和 H5 页面交互(WKWebview 和 UIWebview cookie 设置)

1. UIWebview 1. UIWebview 相对比较简单 直接通过 NSHTTPCookieStorage 设置cookie就能实现。 代码部分 ``` NSURL *cookieHost = [NSURL URLWithString:self.domain]; // 设定 cookie NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties: [NSDictionary dict

Gabriel的专栏 1118

iOS 介绍使用UIWebView和WKWebView加载进度条的代码+demo

简介 如果项目支持iOS7之前的系统版本的话,可以做个系统判断,这里就不介绍了,这里还是推荐使用WKWebView,先介绍下使用这个的好处,然后介绍使用UIWebView和WKWebView加载进度条的代码。 开发App的过程中,常常会遇到在App内部加载网页,通常用UIWebView加载。这个自iOS2开始使用的网页加载器一直是开发的心病:加载速度慢,占用内存多,优化困难。如果加载网页多

974

WKWebView 和UIWebView、网页缓存、网路请求缓存

网页缓存:https://www.jianshu.com/p/f3019d511f36、https://blog.youkuaiyun.com/leikezhu1981/article/details/68491249 网路请求缓存:https://www.cnblogs.com/wendingding/p/3950198.html // //  ViewController.m //  WebVie...

代码解释生活 2947
上一篇: 百度地图开发API
下一篇: 文件查看之UIDocumentInteractionController和UIWebView.WKWebView
Step_Next
博客等级 码龄11年 0粉丝 18原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值