[iOS]-网络请求总结

news/2024/5/2 20:19:29/文章来源:https://blog.csdn.net/m0_52192682/article/details/126281633

目录:

  • 参考的博客:
  • 最原始的网络下载 --- `NSData + NSURL`方式
  • NSURLConnection 和 NSURLSession
    • GET请求
      • 下载完成的事件采用block形式
      • 下载完成的事件采用delegate形式
    • POST请求
    • GET和POST操作的区别
      • 使用情况
        • 使用POST方法
        • 使用GET方法
      • HTTP与HTTPS
  • NSURLSessionConfiguration
    • 创建方式
    • 文件下载
    • 断点续传
  • NSURLSessionTaskTransactionMetrics

参考的博客:

[iOS开发]网络请求合集
NSURLSessionTaskTransactionMetrics
经常用到网络请求,想着总结一下iOS网络请求的部分

iOS开发中的网络下载方式包括NSData(最原始,实际开发基本不会用),NSURLConnection(古老又过气的苹果原生网络框架),NSURLSession(现在流行的苹果网络框架),AFNetworkingSDWebImage以及基于AFNetworking的二次封装框架例如XMNetworkingHYBNetworking等等。

最原始的网络下载 — NSData + NSURL方式

  • 步骤:NSString -> NSURL -> NSData -> UIImage
  • 关键API:URLWithString dataWithContentsOfURL:url imageWithData:data
  • 示例:
	// 在子线程中发送下载文件请求dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{// 创建下载路径NSURL *url = [NSURL URLWithString:@"......"];// NSData的dataWithContentsOfURL:方法下载NSData *data = [NSData dataWithContentsOfURL:url];// 回到主线程,刷新UIdispatch_async(dispatch_get_main_queue(), ^{self.imageView.image = [UIImage imageWithData:data];});});

NSURLConnection 和 NSURLSession

  1. iOS9.0之后,以前使用的NSURLConnection过期,苹果推荐使用NSURLSession来替换NSURLConnection来完成网络请求相关操作
  2. NSURLSession的优势:
    • NSURLSession支持http2.0协议
    • 支持下载任务的时候可以直接把数据下载到磁盘中
    • 支持后台下载和上传
    • 同一个session发送多次请求,只需要建立一次连接(复用了TCP
    • 提供了全局的session并且可以统一配置,使用更加方便
    • 下载的时候时多线程异步处理,效率更高
  3. NSURLSessionTask及其子类
    • NSURLSessionTask本身是一个抽象类,在使用时,通常是根据具体的需求使用它的几个子类:
    • NSURLSessionDataTask可以用来发送常见的GetPost请求,既可以用来上传也可以用来下载
    • NSURLSessionDownloadTask可以用来发送下载请求,专门用来下载数据
    • NSURLSessionUploadTask可以用来发送上传请求,专门用来上传数据

在这里插入图片描述

下面讲解一下GET和POST两种请求的用法,由于下方的讲解可能比较局限,想要参考来实际使用的话请参考该博客:[iOS]-POST和GET网络请求

GET请求

过程如下:

  1. 确定请求路径(一般由公司的后台发开人员以接口文档的方式提供),GET请求参数直接跟在URL后面
  2. 创建请求对象(默认包含了请求头和请求方法【GET】)
  3. 创建会话对象(NSURLSession
  4. 根据会话对象创建请求任务(NSURLSessionDataTask
  5. 执行Task
  6. 得到服务器返回的响应后,解析数据

下载完成的事件采用block形式

  • 第一个API,通过request来提供参数(当然requese是基于URL的)
    //1. 确定请求路径NSURL *url = [NSURL URLWithString:@"http://news-at.zhihu.com/api/4/news/latest"];//2. 创建请求对象NSURLRequest *request = [NSURLRequest requestWithURL:url];//3. 创建会话对象NSURLSession *session = [NSURLSession sharedSession];//4. 根据会话对象创建请求任务NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {if (error == nil) {//6.解析服务器返回的数据//说明:(此处返回的数据是JSON格式的,因此使用NSJSONSerialization进行反序列化处理)NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];NSLog(@"%@",dict);}}];[task resume];
  • 第二个API,直接通过URL来提供参数
dataTaskWithURL:completionHandler:

这两个API就使用上来说无非就是第一个使用requestURL进行了封装,但是要注意直接通过URL来提供请求对象的方法在POST请求种不能使用,因为POST请求需要设置请求头请求体这些额外的东西。

下载完成的事件采用delegate形式

代理形式无非就是将下载的任务在代理函数中去执行:

- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.//1. 确定请求路径NSURL *url = [NSURL URLWithString:@"http://news-at.zhihu.com/api/4/news/latest"];//2. 创建请求对象NSURLRequest *request = [NSURLRequest requestWithURL:url];//3. 创建会话对象//    第一个参数:会话对象的配置信息defaultSessionConfiguration  表示默认配置
//   第二个参数:谁成为代理,此处为控制器本身即self
//   第三个参数:队列,该队列决定代理方法在哪个线程中调用
//   可以传主队列、非主队列 如果不指定线程,则completionHandler和delegate的回调方法,都会在子线程中执行。NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];//4. 根据会话对象创建请求任务NSURLSessionDataTask *task = [session dataTaskWithRequest:request];[task resume];
}//1.接收到服务器响应的时候调用该方法
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler {NSLog(@"%@",response);completionHandler(NSURLSessionResponseAllow);//注意:需要使用completionHandler回调告诉系统应该如何处理服务器返回的数据//默认是取消的/*NSURLSessionResponseCancel = 0,        默认的处理方式,取消NSURLSessionResponseAllow = 1,         接收服务器返回的数据NSURLSessionResponseBecomeDownload = 2,变成一个下载请求NSURLSessionResponseBecomeStream        变成一个流*/
}//2.接收到服务器返回数据的时候会调用该方法,如果数据较大那么该方法可能会调用多次
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {NSLog(@"%@",data);
}//3.当请求完成(成功|失败)的时候会调用该方法,如果请求失败,则error有值
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {NSLog(@"%@",error);
}

POST请求

简单来说 POST请求需要另外单独设置request.HTTPMethod属性

    //1.创建会话对象NSURLSession *session = [NSURLSession sharedSession];//2.根据会话对象创建taskNSURL *url = [NSURL URLWithString:@"http://116.62.21.180:8088/user/get_detail"];//3.创建可变的请求对象NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];//4.修改请求方法为POSTrequest.HTTPMethod = @"POST";//5.设置请求体request.HTTPBody = [@"phone=xxxxxxxxxxxx" dataUsingEncoding:NSUTF8StringEncoding];//设置请求头,这个很重要,一定要按照服务器接口的需求设置对应的请求头[requestTest addValue:@"application/json;UTF-8" forHTTPHeaderField:@"Content-Type"];//6.根据会话对象创建一个Task(发送请求)/*第一个参数:请求对象第二个参数:completionHandler回调(请求完成【成功|失败】的回调)data:响应体信息(期望的数据)response:响应头信息,主要是对服务器端的描述error:错误信息,如果请求失败,则error有值*/NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {if (!error) {//8.解析数据NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];NSLog(@"%@",dict);} else {NSLog(@"%@",error);}}];//7.执行任务[dataTask resume];

POST传输的数据都有以下格式(都是设置Content-Type时的几种类型):

  1. application/json:现在非常常用的一种,用来告诉服务器端消息主体是序列化后的JSON字符串
  2. application/x-www-form-urlencoded:提交的数据按照key1=val1&key2=val2的方式进行编码,keyval都进行了URL转码
  3. multipart/form-data:本次 请求的boundary是什么内容,消息主体例就按照字段个数又分为多个结构类似的部分,被部分都是以-- boundary开始,紧接着是内容描述消息,然后是回车,最后是字段具体内容(文本或二进制)。
  4. text/xml: 这种直接传的xml格式

GET和POST操作的区别

区别:

  1. GET向服务器获取数据,POST向服务器发送请求
  2. GET会把查询字符串的参数追加到URL的末尾,POST请求则把数据作为请求的主体来提交,可以包含非常多的数据,因此客户可以看到GET提交的参数,POST则不可以
  3. GET请求提交的数据直接加到URL的末尾,所以大小有限制,而POST则没有
  4. POST安全性比GET
  5. 对于get方式,服务器端有Request.QueryString来获取变量的值,对于post方式,服务器用Request.Form来获取提交的数据
  6. get形式的URL对搜索引擎更加友好,可以提高搜索引擎排名。而POST甚至会阻止爬虫和搜索引擎的访问

使用情况

使用POST方法

  1. 请求的结果有持续性的影响改变,比如向数据库内添加新的数据行
  2. 表单收集的数据过多,若使用get方式会使URL过长
  3. 要传送的数据不是采用7位的ASCII编码

使用GET方法

  1. 请求是为了查找资源,表单的数据只是用来帮助搜索
  2. 请求结果无持续性的影响改变
  3. 收集的数据及HTML表单内的输入字段名称的总长不超过1024个字节

HTTP与HTTPS

iOS9为了增强数据访问安全,将所有的HTTP请求都改为了 HTTPS,现在苹果默认支持请求的URL格式是HTTPS,使用HTTP则会被认定为不安全从而请求失败

若一定要使用HTTP,就需要对Info文件进行一些配置,如下:
在这里插入图片描述
我们需要在App Transport Security Settings下创建Allow Aebitrary Loads,并将其TypeBoolean类型的Value设置为YES;如本身就没有App Transport Security Settings的话则需要创建一个

那么HTTPHTTPS有什么区别呢?
HTTP协议运行在TCP之上,明文运输,客户端与服务器端都无法验证对方的身份;HTTPS是身披SSLSecure Socket Layer)外壳的Http,运行于SSL上,SSL运行在TCP上,是添加了加密和认证机制的HTTPHttps的加密机制是一种共享密钥加密和公开密钥加密并用的混合加密机制

  • 端口不同:HttpHttps使用不同的连接方式,http80https443
  • 资源消耗:和Http通信相比,Https通信会由于加减密处理消耗更多的CPU和内存资源
  • 开销:Https通信需要证书,而证书一般需要向认证机构购买

NSURLSessionConfiguration

NSURLSession创建的Task任务,只能在任务结束的completionHandlerblock中获取到结束后的数据,想要使用这些数据的话也需要等到下载完成了,才能拿来使用,至于下载的过程中,想要使用数据不可能。而NSURlSessionConfiguration就是一个代理,是为了监控下载过程的。

所以除了上面的两种session的创建方式sharedSessionsessionWithConfiguration:delegate:delegateQueue:,还有sessionWithConfiguration:可以帮助我们监控下载过程

创建方式

NSURLSessionConfiguration可以设置请求的Cookie密钥缓存请求头等参数,将网络请求的一些配置参数从NSURLSession中分离出来

NSURLSessionConfiguration提供defaultSessionConfiguration的方式创建,但这并不是单例方法,而是类方法,创建的是不同对象。通过这种方式创建的configuration,并不会共享cookiecache密钥等,而是不同configuration都需要单独设置

文件下载

这里URLhttp://vfx.mtime.cn/Video/2017/03/31/mp4/170331093811717750.mp4一个在线的视频流

简单,通过Session创建一个downloadTask,并调用resume即可开启一个下载任务(此处例子用的是delegate代理的请求方式)

NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];NSURL *url = [NSURL URLWithString:@"http://vfx.mtime.cn/Video/2017/03/31/mp4/170331093811717750.mp4"];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request];
[downloadTask resume];// 从服务器接收数据,下载进度回调
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTaskdidWriteData:(int64_t)bytesWrittentotalBytesWritten:(int64_t)totalBytesWritten
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {}// 下载完成后回调
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
didFinishDownloadingToURL:(NSURL *)location {}

当然我们也可以调用suspend将下载任务挂起,随后调用resume方法继续下载任务,suspendresume需要是成对的。但是suspend挂起任务是有超市设置的,默认是60s,如果超时系统会将TCP连接断开,我们再调用resume是失效的。可以通过NSURLSessionConfigurationtimeoutIntervalForResource来设置上传和下载的资源耗时。suspend只针对于下载任务,其他任务挂起后将会重新开始

断点续传

断点续传就是从文件上次中断的地方重新开始下载或者上传数据,而不是从头开始

如果使用断点续传,不仅仅是客户端的工作,还需要服务器支持断点续传功能,否则无法生成正确的resumeData

如何验证服务器是否支持断点续传呢?

我们可以通过下载文件的时候的响应头来查看:
根据苹果官方文档的描述:

只有满足以下条件,才能恢复下载:

  • 自您第一次请求资源以来,资源没有变化
  • 该任务是HTTPHTTPS GET请求 必须是get请求
  • 服务器在其响应中提供ETag或者Last-Modified标题(或两者) 和第一条基本上是相同
  • 服务器支持字节范围请求 如:服务器响应头包含accept-range:Btyes
  • 系统尚未删除临时文件以响应磁盘空间压力 本地缓存文件存在

满足上述条件的,才能使用断点续传功能
其次,使用断点续传的时候,客户端请求的range是比如说19799+,服务器此时返回的文件的部分数据,服务器响应码必须是206,不可以是200或者其他状态码,否则客户端会从头下载

HTTP协议支持断点续传操作,在开始下载请求时通过请求头设置Range字段,标示从什么位置开始下载

Range:bytes=512000-

服务端收到客户端请求后,开始从512kb的位置开始传输数据,并通过Content-Range字段告知客户端传输数据的开始位置

Content-Range:bytes 512000-/1024000

downloadTask任务开始请求后,可以调用cancelByProducingResumeData:方法可以取消下载,并且可以获得一个resumeDataresumeData中存放一些断点下载的信息。可以将resumedata写到本地,后面通过这个文件可以进行断点续传。

NSString *library = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES).firstObject;
NSString *resumePath = [library stringByAppendingPathComponent:[self.downloadURL md5String]];//以URL为值,创建一个path
[self.downloadTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {[resumeData writeToFile:resumePath atomically:YES];//将得到的resumeData传入url的路径中
}];

在创建下载任务前,可以判断当前任务有没有之前待恢复的任务,如果有的话调用downloadTaskWithResumeData:方法并传入一个resumeData,可以恢复之前的下载,并重新创建一个downloadTask任务:

NSString *library = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES).firstObject;
NSString *resumePath = [library stringByAppendingPathComponent:[self.downloadURL md5String]];
NSData *resumeData = [[NSData alloc] initWithContentsOfFile:resumePath];
self.downloadTask = [self.session downloadTaskWithResumeData:resumeData];
[self.downloadTask resume];

通过suspendresume这种方式挂起的任务,downloadTask是同一个对象,而通过cancel然后resumeData恢复的任务,会创建一个新的downloadTask任务

当调用downloadTaskWithResumeData方法恢复下载之后,会产生回调下面的方法:

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTaskdidResumeAtOffset:(int64_t)fileOffset
expectedTotalBytes:(int64_t)expectedTotalBytes;

fileOffset是上次文件的下载大小
expectedTotalBytes是预估的文件总大小

通过这两个参数,我们也能给出某些比例之类的。比如下载了多少等等

NSURLSessionTaskTransactionMetrics

NSURLSessionTaskTransactionMetrics是封装在执行会话任务期间收集的性能指标的对象,其中的属性都是用来做统计的,功能都是记录某个值,并没有逻辑上的意义

每个NSURLSessionTaskTransactionMetrics对象由一个请求响应属性组成,对应于相应任务的请求和响应

它还包含时间度量,从fetchStartDate开始,以responseEndDate结束,以及其他特征,如networkProtocolNameresourceFetchType

该类定义在任务执行期间为请求/响应事务收集的性能指标:

typedef NS_ENUM(NSInteger, NSURLSessionTaskMetricsResourceFetchType) {NSURLSessionTaskMetricsResourceFetchTypeUnknown, 无法确定获取资源的方式。NSURLSessionTaskMetricsResourceFetchTypeNetworkLoad,  资源是通过网络加载的。NSURLSessionTaskMetricsResourceFetchTypeServerPush,   资源由服务器推送到客户机。NSURLSessionTaskMetricsResourceFetchTypeLocalCache,  从本地存储中检索资源。
} API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0));

下面我们就简单展示一下其收集性能指标的顺序逻辑,具体各个属性的含义大家可以详见该博客:NSURLSessionTaskTransactionMetrics

苹果官方文档对其的讲解如下:
请添加图片描述
翻译版如下:
请添加图片描述
图里面的这个流程图解释的非常详细,还有如果任务由于什么原因失败的话,domainLookupEndDate属性和随后要记录的属性值都会为nil

可以看到加密的安全连接部分是TLS的连接部分,我们在这里浅浅介绍一下TLS
安全传输层协议(TLS)用于在两个通信应用程序之间提供保密性和数据完整性
该协议由两层组成: TLS 记录协议(TLS Record)和 TLS 握手协议(TLS Handshake

@interface NSURLSessionTaskTransactionMetrics : NSObject
// 请求对象
@property (copy, readonly) NSURLRequest *request;
// 响应对象,请求失败可能会为nil
@property (nullable, copy, readonly) NSURLResponse *response;
// 请求开始时间
@property (nullable, copy, readonly) NSDate *fetchStartDate;
// DNS解析开始时间
@property (nullable, copy, readonly) NSDate *domainLookupStartDate;
// DNS解析结束时间,如果解析失败可能为nil
@property (nullable, copy, readonly) NSDate *domainLookupEndDate;
// 开始建立TCP连接时间
@property (nullable, copy, readonly) NSDate *connectStartDate;
// 结束建立TCP连接时间
@property (nullable, copy, readonly) NSDate *connectEndDate;
// 开始TLS握手时间
@property (nullable, copy, readonly) NSDate *secureConnectionStartDate;
// 结束TLS握手时间
@property (nullable, copy, readonly) NSDate *secureConnectionEndDate;
// 开始传输请求数据时间
@property (nullable, copy, readonly) NSDate *requestStartDate;
// 结束传输请求数据时间
@property (nullable, copy, readonly) NSDate *requestEndDate;
// 接收到服务端响应数据时间
@property (nullable, copy, readonly) NSDate *responseStartDate;
// 服务端响应数据传输完成时间
@property (nullable, copy, readonly) NSDate *responseEndDate;
// 网络协议,例如http/1.1
@property (nullable, copy, readonly) NSString *networkProtocolName;
// 请求是否使用代理
@property (assign, readonly, getter=isProxyConnection) BOOL proxyConnection;
// 是否复用已有连接
@property (assign, readonly, getter=isReusedConnection) BOOL reusedConnection;
// 资源标识符,表示请求是从Cache、Push、Network哪种类型加载的
@property (assign, readonly) NSURLSessionTaskMetricsResourceFetchType resourceFetchType;
// 本地IP
@property (nullable, copy, readonly) NSString *localAddress;
// 本地端口号
@property (nullable, copy, readonly) NSNumber *localPort;
// 远端IP
@property (nullable, copy, readonly) NSString *remoteAddress;
// 远端端口号
@property (nullable, copy, readonly) NSNumber *remotePort;
// TLS协议版本,如果是http则是0x0000
@property (nullable, copy, readonly) NSNumber *negotiatedTLSProtocolVersion;
// 是否使用蜂窝数据
@property (readonly, getter=isCellular) BOOL cellular;
//两个初始化方法
- (instancetype)init API_DEPRECATED("Not supported", macos(10.12,10.15), ios(10.0,13.0), watchos(3.0,6.0), tvos(10.0,13.0));
+ (instancetype)new API_DEPRECATED("Not supported", macos(10.12,10.15), ios(10.0,13.0), watchos(3.0,6.0), tvos(10.0,13.0));@end

可以看到里面有一堆属性,然后还有一个init方法和一个new方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_4895.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

APS智能排产助力印染行业进行精细化管理

根据国家统计局数据,2022年1-6月,规模以上印染企业营业收入1500.66亿元,同比增长11.10%;实现利润总额57.18亿元,同比增长13.79%;成本费用利润率4.04%,同比提高0.10个百分点;销售利润…

大学公众号题库API 网课查题题库接口API接口

大学公众号题库API 网课查题题库接口API接口 本平台优点: 多题库查题、独立后台、响应速度快、全网平台可查、功能最全! 1.想要给自己的公众号获得查题接口,只需要两步! 2.题库: 题库:题库后台http://ch…

Problem P04. [算法课分治] 找到 k 个最小数

先sort排序,在输出最小的k个数。#include<iostream> #include<bits/stdc++.h> #include<cstdio>using namespace std;int n, k; int arr[10005];int main() {scanf("%d %d", &n, &k);for (int i = 0; i < n; i++){scanf("%d"…

【Hive】各种join连接用法

目录 一、简介 二、创建数据 1、数据概览 2、创建hive表并插入数据 三、join连接测试 1、join(inner join) 2、left join(left outer join) 3、right join(right outer join) 4、full join(full outer join) 5、left semi join 6、map side join 四、join 和 left …

定时任务cron

原文链接 1 格式 {秒数} {分钟} {小时} {日期} {月份} {星期} {年份(可为空)} 2 用法 "30 * * * * ? " 每半分钟触发任务"30 10 * * * ? " 每小时的10分30秒触发任务"30 10 1 * * ? " 每天1点10分30秒触发任务"30 10 1 20 * ? &quo…

【UCIe】UCIe D2D Adapter 介绍

&#x1f525;点击查看精选 UCIe 系列文章&#x1f525; &#x1f525;点击进入【芯片设计验证】社区&#xff0c;查看更多精彩内容&#x1f525; &#x1f4e2; 声明&#xff1a; &#x1f96d; 作者主页&#xff1a;【MangoPapa的CSDN主页】。⚠️ 本文首发于CSDN&#xff0…

springboot大学生兼职网站毕业设计源码311734

springboot大学生兼职网站 摘 要 信息化社会内需要与之针对性的信息获取途径&#xff0c;但是途径的扩展基本上为人们所努力的方向&#xff0c;由于站在的角度存在偏差&#xff0c;人们经常能够获得不同类型信息&#xff0c;这也是技术最为难以攻克的课题。针对大学生兼职网站等…

React + Dva + Antd + Umi 快速入门

最近一个项目用了React + Dva + Antd + Umi 技术栈基础框架概念 React前端三大框架之一。Dva由阿里架构师 sorrycc 带领 team 完成的一套前端框架,在作者的 github 里是这么描述它的:”dva 是 react 和 redux 的最佳实践”。Antd是阿里的一套开箱即用的中台前端/设计解决方案…

Vue模板语法上集(02)

今日份分享内容&#xff1a; 一、插值&#xff08;该代码块会放在末尾一并展示&#xff09; 1、文本插值 2、使用v-html指令用于输出html代码 3、属性 HTML属性中的值应使用v-bind指令 4、表达式 5、class 样式绑定 二、指令 1、 v-if 2、 v-show 3、v-for&…

Docker高级-1.复杂安装示例(mysql主从复制、redis集群)

目录 一、mysql主从复制 1.1 主服务器 1.2 从服务器 二、redis集群 2.1 问题引入-1~2亿条数据需要缓存&#xff0c;如何设计这个存储案例 2.1.1 方案一-哈希取余分区 2.1.2 方案二-一致性哈希算法分区 2.1.3 方案三-哈希槽分区 2.2 redis集群搭建演示 2.3 数据读写测试…

mybatis-plus-generator 配置不生成 entity, controller, mapper 等

3.5.2版本 有需求不生成controller 于是baidu 发现如下方法.templateConfig(builder -> builder.controller(""))配置后确实不生成controller又有需求不生成entity 尝试以下代码未果.templateConfig(builder -> builder.entity(""))于是查看源代码和…

【编程题】【Scratch二级】2022.06 画正方形

画正方形 在舞台正中央绘制一个边长为200的正方形。 1. 准备工作 &#xff08;1&#xff09;保留默认小猫角色并隐藏角色&#xff1b; &#xff08;2&#xff09;默认空白背景&#xff1b; &#xff08;3&#xff09;添加画笔模块。 2. 功能实现 &#xff08;1&#xff…

K8s(kubernetes)介绍以及原理解析

K8s&#xff08;kubernetes&#xff09; 云原生 服务部署模式 物理机模式–>虚拟化模式–>云端模式&#xff08;云原生模式&#xff09; K8s简介及架构 容器编排技术&#xff0c;用来管理容器 但是不直接管理容器&#xff0c;通过管理pod来间接管理容器 pod是k8s最小…

Android的handler消息收发处理——子线程与主线程(UI线程)间的通信

目录 写在前面 基础概念 什么是handler&#xff1f; 什么是looper&#xff1f; 什么是消息队列&#xff08;MessageQueue&#xff09;&#xff1f; 在子线程中使用子线程中的数据更新UI线程 主线程与子线程通信实例&#xff08;程序代码&#xff09; 子线程获取主线程h…

01.Singleton单件(单例)

一&#xff1a;动机&#xff08;Motivation&#xff09; <1>在软件系统中&#xff0c;经常有这样一些特殊的类&#xff0c;必须保证它们在系统中只存在一个实例&#xff0c;才能确保它们的逻辑正确性、以及良好的效率。 <2>如何绕过常规的构造器&#xff0c;提供一…

堆技巧 数组反向越界泄露地址

四川省2021信息安全技术大赛 classroom 痛苦痛苦痛苦&#xff0c;调了半天才找到数组起始地址&#xff0c;还是自己太菜了&#xff0c;好好记录一下这题 题目给了libc&#xff0c;2.31的题 嗯&#xff0c;可以考虑覆盖got表或者hook函数 打开ida发现是c的题&#xff0c;认真…

目前期货开户手续费比较透明

一、期货公司手续费 只要交易买卖期货就会产生期货手续费&#xff0c;不同的期货交易所&#xff0c;商品期货手续费收取标准不一样&#xff0c;首先&#xff0c;我们需要弄清楚期货手续费的组成和分类&#xff1a; 期货实际收取的手续费期货交易所手续费期货公司额外加收的佣…

flask-sqlalchemy连接数据库

1、安装flask_sqlalchemy和pymysql包 pip install flask-sqlalchemy pip install pymysql 2、进行配置 使用Flask-SQLAlchemy扩展操作数据库&#xff0c;首先需要通过URL建立数据库连接&#xff0c;必须保存到Flask配置对象的SQLALCHEMY_DATABASE_URI中。 HOSTNAME 127.0…

MySQL入门:数据库是什么 | SQL是什么 | MySQL是什么

文章目录数据库数据库管理系统&#xff08;DBMS&#xff09;的种类数据库的结构什么是SQLMySQLSQL语句 | 种类SQL 的基本书写规则存储引擎参考与总结全文约 3235 字&#xff0c;预计阅读时长&#xff1a; 9分钟数据库 存储数据用文件就可以了&#xff0c;为什么还要弄个数据库?…

dubbo和springCloud

Dubbo 高性能的java RPC框架 架构 init:初始化 async:异步 sync同步 0:需要容器启动例如Tomcat 1:注册ip端口以及一些东西到注册中心 2:订阅服务快速入门 Zookeeper(官方推荐注册中心,同时还有Redis,Simper,Multicast,Nacos等) 安装:默认端口2181 Dubbo快速入门 传统方法,需要…