-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontent.json
More file actions
1 lines (1 loc) · 119 KB
/
content.json
File metadata and controls
1 lines (1 loc) · 119 KB
1
{"meta":{"title":"Aferica的个人博客","subtitle":null,"description":null,"author":"aferica","url":"http://http://www.aferica.site","root":"/"},"pages":[],"posts":[{"title":"记一次Nginx无法使用https的问题(开启Ubuntu防火墙)","slug":"记一次Nginx无法使用https的问题","date":"2019-10-17T09:20:26.000Z","updated":"2019-10-17T09:43:46.469Z","comments":true,"path":"post/72cb0b46.html","link":"","permalink":"http://http://www.aferica.site/post/72cb0b46.html","excerpt":"","text":"起因前几天因为自己在瞎搞项目,导致自己的服务器又装了一个apache,然后就悲剧了,自己的服务彻底崩了 过程刚开始,我卸载了apache和Nginx,重新安装了自己的Nginx,重新配置后仍然无效,只能看到Welcome to nginx!(我也是去查看这个来检查自己的Nginx是否启动的时候才发现原来自己多装了一个apache),然后,我就一直以为是自己的Nginx有问题,不断重启测试,就是不行,然后我就打开我唯一的一个http访问的地址,发现可以访问,于是我又去查询为什么https无法访问,很多都是说是因为防火墙的问题,我一直没在意,因为之前好好的可以访问的,以为443端口放开了,又折腾了好久,实在是没法了,我去查了一下防火墙,卧槽?怎么没放开,最终放开后解决了问题。 总结 1.先打开ip,查看服务是否启动 2.查看使用http访问的地址,验证Nginx配置是否生效 3.查看防火墙 Ubuntu防火墙使用命令查看开放端口1ufw status 开放端口1ufw allow 443 重启防火墙1sudo ufw reload","categories":[{"name":"Ubuntu","slug":"Ubuntu","permalink":"http://http://www.aferica.site/categories/Ubuntu/"}],"tags":[{"name":"Ubuntu","slug":"Ubuntu","permalink":"http://http://www.aferica.site/tags/Ubuntu/"},{"name":"Https","slug":"Https","permalink":"http://http://www.aferica.site/tags/Https/"},{"name":"Nginx","slug":"Nginx","permalink":"http://http://www.aferica.site/tags/Nginx/"},{"name":"防火墙","slug":"防火墙","permalink":"http://http://www.aferica.site/tags/防火墙/"}]},{"title":"mongoDB中聚合aggregate使用(二)","slug":"mongoDB中聚合aggregate使用(二)","date":"2019-08-07T08:04:21.000Z","updated":"2019-08-08T09:31:59.500Z","comments":true,"path":"post/27f70779.html","link":"","permalink":"http://http://www.aferica.site/post/27f70779.html","excerpt":"","text":"在之前的博文mongoDB中聚合aggregate使用中,我简单的介绍了一些常用的aggregate方法,在这篇文章中,我主要介绍另外的几个比较常用方法。 好文推荐在使用和测试方法时,我在网上找到了这篇教程,很详细,且是中文文档,值得一读MongoDB学习笔记 方法介绍$lookup 用于对同一数据库中的另外一个非分片集合执行左外连接操作,相当于left join 用法12345678{ $lookup: { from: '被左外连接的集合', localField: '输入文档中用于匹配(等于)的字段', foreignField: '被连接集合中用于匹配的字段', as: '被连接文档在输出中对应的字段名' }} 测试数据订单表12345db.orders.insert([ { \"_id\" : 1, \"item\" : \"almonds\", \"price\" : 12, \"quantity\" : 2 }, { \"_id\" : 2, \"item\" : \"pecans\", \"price\" : 20, \"quantity\" : 1 }, { \"_id\" : 3 }]) 物品表12345678db.inventory.insert([ { \"_id\" : 1, \"sku\" : \"almonds\", description: \"product 1\", \"instock\" : 120 }, { \"_id\" : 2, \"sku\" : \"bread\", description: \"product 2\", \"instock\" : 80 }, { \"_id\" : 3, \"sku\" : \"cashews\", description: \"product 3\", \"instock\" : 60 }, { \"_id\" : 4, \"sku\" : \"pecans\", description: \"product 4\", \"instock\" : 70 }, { \"_id\" : 5, \"sku\": null, description: \"Incomplete\" }, { \"_id\" : 6 }]) 示例1234567891011# 订单左外连接库存db.orders.aggregate([ { $lookup: { from: \"inventory\", localField: \"item\", foreignField: \"sku\", as: \"inventory_docs\" } }]) 1234567891011// 输出文档示例(只示例一条结果){ \"_id\" : 1, \"item\" : \"abc\", \"price\" : 12, \"quantity\" : 2, // 匹配的被连接文档,数组形式 \"inventory_docs\" : [ { \"_id\" : 1, \"sku\" : \"abc\", \"description\": \"product 1\", \"instock\" : 120 } ]} $replaceRoot 提升输入文档中的一个内嵌文档,将其作为根文档,代替原有文档,简单理解就是使用结果代替原有文档后继续操作,相当于mysql之类将查询到的结果生成一个虚拟表,再进行操作 多用于一个Object字段 和$mergeObjects、$lookup配合使用更佳 用法12345{ $replaceRoot: { newRoot: <replacementDocument> } } 测试数据用户表12345db.people.insert([ { \"_id\" : 1, \"name\" : \"Arlene\", \"age\" : 34, \"pets\" : { \"dogs\" : 2, \"cats\" : 1 } }, { \"_id\" : 2, \"name\" : \"Sam\", \"age\" : 41, \"pets\" : { \"cats\" : 1, \"fish\" : 3 } }, { \"_id\" : 3, \"name\" : \"Maria\", \"age\" : 25 }]) 示例将pets字段信息提取出来形成一张表123db.people.aggregate([ { $replaceRoot: { newRoot: { $mergeObjects: [ { dogs: 0, cats: 0, birds: 0, fish: 0 }, \"$pets\" ] }} }]) 1234// 输出文档示例{ \"dogs\" : 2, \"cats\" : 1, \"birds\" : 0, \"fish\" : 0 }{ \"dogs\" : 0, \"cats\" : 1, \"birds\" : 0, \"fish\" : 3 }{ \"dogs\" : 0, \"cats\" : 0, \"birds\" : 0, \"fish\" : 0 } $mergeObjects 3.6以上版本才可以使用 顾名思义,用于合并对象 和$replaceRoot、$lookup配合使用更佳 用法1234# 对单个字段或对象使用{ $mergeObjects: <document> }# 对多个字段或对象使用{ $mergeObjects: [ <document1>, <document2>, ... ] } 官方演示: 测试数据使用上述$lookup测试数据 示例上述使用$lookup结果如下1234567891011// 输出文档示例(只示例一条结果){ \"_id\" : 1, \"item\" : \"abc\", \"price\" : 12, \"quantity\" : 2, // 匹配的被连接文档,数组形式 \"inventory_docs\" : [ { \"_id\" : 1, \"sku\" : \"abc\", \"description\": \"product 1\",, \"instock\" : 120 } ]} 添加使用$mergeObjects:12345678910111213db.orders.aggregate([ { $lookup: { from: \"inventory\", localField: \"item\", foreignField: \"sku\", as: \"inventory_docs\" } }, { $replaceRoot: { newRoot: { $mergeObjects: [ { $arrayElemAt: [ \"$inventory_docs\", 0 ] }, \"$$ROOT\" ] } } }]) 1234567891011// 输出文档示例(只示例一条结果){ \"_id\" : 1, \"item\" : \"abc\", \"price\" : 12, \"quantity\" : 2, \"_id\" : 1, \"sku\" : \"abc\", \"description\": \"product 1\", \"instock\" : 120} $addFields 为每个输入文档添加额外的字段,可以用来处理数据 用法1{ $addFields: { <newField>: <expression>, ... } } 测试数据12345678910111213141516db.scores.insert([ { _id: 1, student: \"Maya\", homework: [ 10, 5, 10 ], quiz: [ 10, 8 ], extraCredit: 0 } { _id: 2, student: \"Ryan\", homework: [ 5, 6, 5 ], quiz: [ 8, 8 ], extraCredit: 8 }]) 示例123456789101112db.scores.aggregate([ { $addFields: { totalHomework: { $sum: \"$homework\" } , totalQuiz: { $sum: \"$quiz\" } } }, { $addFields: { totalScore: { $add: [ \"$totalHomework\", \"$totalQuiz\", \"$extraCredit\" ] } } }]) 1234567891011121314151617181920{ \"_id\" : 1, \"student\" : \"Maya\", \"homework\" : [ 10, 5, 10 ], \"quiz\" : [ 10, 8 ], \"extraCredit\" : 0, \"totalHomework\" : 25, \"totalQuiz\" : 18, \"totalScore\" : 43}{ \"_id\" : 2, \"student\" : \"Ryan\", \"homework\" : [ 5, 6, 5 ], \"quiz\" : [ 8, 8 ], \"extraCredit\" : 8, \"totalHomework\" : 16, \"totalQuiz\" : 16, \"totalScore\" : 40} 示例2在使用$lookup将数据中的字符串转为ObjectId1{ $addFields: { \"新字段名称\": { \"$toObjectId\": \"$字段名\" }}}, $sortByCount 根据指定表达式的值对输入文档进行分组,并且计算每个分组中文档的数量,相当于$group和$sort组合使用 用法1234{ $sortByCount: <expression> } # 字段名,需要添加$# 等价于以下两个Stage的组合:{ $group: { _id: <expression>, count: { $sum: 1 } } },{ $sort: { count: -1 } }","categories":[{"name":"数据库","slug":"数据库","permalink":"http://http://www.aferica.site/categories/数据库/"},{"name":"mongoDB","slug":"数据库/mongoDB","permalink":"http://http://www.aferica.site/categories/数据库/mongoDB/"}],"tags":[{"name":"mongoDB","slug":"mongoDB","permalink":"http://http://www.aferica.site/tags/mongoDB/"}]},{"title":"Flutter学习(六):视频播放","slug":"Flutter学习(六):视频播放","date":"2019-08-05T13:18:09.000Z","updated":"2019-08-07T08:00:39.079Z","comments":true,"path":"post/8aa1c451.html","link":"","permalink":"http://http://www.aferica.site/post/8aa1c451.html","excerpt":"","text":"在使用Flutter视频播放组件时,最开始我使用了官方组件video_player,但是在使用时遇到了报错,查看Github和Google并没有解决,于是我在Flutter组件仓库中查找,最后选择了使用flutter_ijkplayer。 选择原因 兼容视频格式多,可自行编译 可以定制自己的UI 该组件是基于bilibili/ijkplayer,本人对B站挺有好感的 使用方便,有中文文档 简介GitHub地址:https://github.com/CaiJingLong/flutter_ijkplayer 使用引入123# pubspec.yamldependencies: flutter_ijkplayer: ${lastes_version} 页面使用12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970import 'package:flutter/material.dart';import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';class VideoInfoPage extends StatefulWidget { @override State<StatefulWidget> createState() => VideoInfoState();}class VideoInfoState extends State<VideoInfoPage> { String selectPlayUrl = ''; // 定义控制器 IjkMediaController controller = IjkMediaController(); @override void initState() { super.initState(); getVideoInfo(); } @override void dispose() { // 重要,一定要在销毁页面时销毁播放器,否则会出现后台仍在播放有声音的问题 controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { // TODO: implement build return Scaffold( appBar: AppBar( title: Text('影片信息'), ), body: Container( child: Stack( children: <Widget>[ Positioned( top: 0, left: 0.0, right: 0.0, height: MediaQuery.of(context).size.width / 16 * 9, child: Container( // 自定义播放器高度 height: MediaQuery.of(context).size.width / 16 * 9, child: IjkPlayer(mediaController: controller), ), ), // ... 其它信息 ] ), ), ); } getVideoInfo() async { String palyUrl = 'https://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_20mb.mp4'; setState(() { selectPlayUrl = palyUrl; }); await controller.setNetworkDataSource( palyUrl, autoPlay: true //自动播放 ); }} 切换来源可以为按钮添加点击事件123456789101112131415// ...onClick: () async { String playUrl = 'xxx'; setState(() { selectPlayUrl = playUrl; }); // 这个方法调用后,会释放所有原生资源,但重新设置dataSource依然可用 await controller.reset(); // 重新设置播放地址 controller.setNetworkDataSource( playUrl, autoPlay: false );},// ... 更多介绍请详见官方文档 效果展示","categories":[{"name":"Flutter","slug":"Flutter","permalink":"http://http://www.aferica.site/categories/Flutter/"}],"tags":[{"name":"Flutter","slug":"Flutter","permalink":"http://http://www.aferica.site/tags/Flutter/"},{"name":"移动开发","slug":"移动开发","permalink":"http://http://www.aferica.site/tags/移动开发/"},{"name":"视频播放器","slug":"视频播放器","permalink":"http://http://www.aferica.site/tags/视频播放器/"},{"name":"flutter_ijkplayer","slug":"flutter-ijkplayer","permalink":"http://http://www.aferica.site/tags/flutter-ijkplayer/"}]},{"title":"使用CloudFlare为自己的网站保驾护航","slug":"使用CloudFlare为自己的网站保驾护航","date":"2019-07-30T07:44:43.000Z","updated":"2019-08-01T07:48:26.815Z","comments":true,"path":"post/18c91674.html","link":"","permalink":"http://http://www.aferica.site/post/18c91674.html","excerpt":"","text":"前言作为一位程序员,尤其是一位前端程序员,拥有一个自己的网站或者博客是很平常的一件事。无论作为自己的自由地,肆意发挥和实现自己的创意或者想法,还是作为展示自己的窗口,都很不错。作为一个私人网站,我们不可能,也没有时间去注意网络安全,但是,一旦发生,后果有可能十分严重。另外,大多数人应该都只有一个域名或者一个自己的服务器,有些内容是自己想要展示的,另外一些又是自己想要隐藏的,防止有心之人通过展示的部分获取到服务器地址,从而给自己造成一些麻烦也是很有必要的,这就需要推荐这篇博客的主角————CloudFlare。 友情提示(重要)由于CloudFlare是一家国外的云服务提供商,在国内访问速度受到比较明显的影响,因此,如果你觉得速度大于安全的话,并不推荐你使用。 简介Cloudflare以向客户提供网站安全管理、性能优化及相关的技术支持为主要业务,帮助网站阻止来自网络的黑客攻击、垃圾邮件等,并提升网页的浏览速度。官网:https://www.cloudflare.com/ 使用教程1. 注册/登录这个就不多描述了 2. 添加自己的域名点击右上角”Add site”,添加域名点击Next,Cloudflare会自动查找该域名下的DNS记录并导入选择套餐,免费版就可以了(当然,如果你是土豪,任意就好),点击Confirm plan确认弹框点击Confirm确认点击Continue继续 关键步骤:更改自己域名的DNS解析地址,点击Continue继续(可稍后在改,直接继续)进入控制台主页 3. 配置3.1 等待DNS解析地址更新当出现下图中的Complete your nameserver setup提示,代表DNS解析地址未设置成Cloudflare地址,或未更新在上面更改DNS解析地址后,点击Re-check now重新检查状态返回主页Active代表DNS解析地址更新成功,可以使用Pending Nameserver Update代表DNS解析地址未更新,暂不可用 3.2 DNS解析配置点击上方第三个DNS菜单,进入DNS解析配置页面点击Add Record可以添加记录代表使用Cloudflare的功能,如防攻击,https等代表不使用,仅仅只作为DNS解析服务器 3.3 Https加密点击上方第三个Crypto菜单 3.3.1 SSL如上图,可选四种模式,分别含义Off:不使用加密连接Flexible:您的网站访问者和Cloudflare之间有加密连接,但是从Cloudflare到您的服务器没有加密。即半程加密。优点在于:你的网站不需要SSL证书,用户也能实现SSL加密访问。Full:全程加密,即从你的网站到CDN服务器再到用户,全程都是SSL加密的。优点在于:只要你的服务器有SSL证书(不管是自签名证书还是购买的SSL),就可以实现SSL加密访问。Full(strict):全程加密,它与Full SSL的区别在于你的服务器必须是安装了那些已经受信任的SSL证书(即购买的SSL证书),否则无法开启SSL加密访问。 3.3.2 Origin Certificates由于使用Full或者Full(strict)都需要在服务器安装证书,如果你有多个子域名,并且都想使用https,那么这项功能对你来说十分方便如上图示例,我添加了7个子域名(可以共用一个证书),有效期15年(完全不用考虑过期问题),简直不要太舒服 点击Create Certificate按钮开始创建 输入自己想要添加的域名,如果想要添加子域名,例如api,只需要输入api后点击回车即可 选择时长(很显然,当然选择15年了) 点击Next按钮生成 生成弹框中,将Origin Certificate内容保存为xxx.pem文件,将Private key内容保存为xxx.key文件(如果没有Private key,重新生成即可) 配置Nginx1234567891011121314151617server { listen 443; server_name xxx.xxx; // 域名或者子域名 ssl on; ssl_certificate xxx.pem; // 上保存的.pem文件的全路径 ssl_certificate_key xxx.key; // 上保存的.key文件的全路径 ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #按照这个协议配置 ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; #按照这个套件配置 ssl_prefer_server_ciphers on; client_max_body_size 20m; // 网页路径配置} 3.3.3 Always Use HTTPS自动将Http请求重定向为Https,默认关闭 3.3.4 Automatic HTTPS Rewrites会将网站使用http请求的数据如cdn,js文件等使用https请求,默认关闭 3.4 配置过程中遇到问题在配置时,由于生效需要一定时间(官方说是24小时),所以如果出现浏览器找到地址,或者ERR_SSL_PROTOCOL_ERROR错误,以及一些莫名其妙的问题,请等待 测试对速度的影响开篇就提到了,使用CloudFlare会对速度有些影响,具体测试:不使用(3.2中配置):平均速度16ms使用后(3.2中配置):平均速度177ms影响速度比较明显,所以具体是否使用,请结合自身实际","categories":[{"name":"云服务","slug":"云服务","permalink":"http://http://www.aferica.site/categories/云服务/"},{"name":"CloudFlare","slug":"云服务/CloudFlare","permalink":"http://http://www.aferica.site/categories/云服务/CloudFlare/"}],"tags":[{"name":"CloudFlare","slug":"CloudFlare","permalink":"http://http://www.aferica.site/tags/CloudFlare/"},{"name":"Https","slug":"Https","permalink":"http://http://www.aferica.site/tags/Https/"}]},{"title":"好用软件推荐-Windows篇","slug":"好用软件推荐-Windows篇","date":"2019-07-27T07:12:08.000Z","updated":"2019-07-30T08:13:37.670Z","comments":true,"path":"post/eee036c1.html","link":"","permalink":"http://http://www.aferica.site/post/eee036c1.html","excerpt":"","text":"在日常使用过程中,我积累了一些好用的软件,方便日常使用和工作使用。 下载类PanDownload ⭐️⭐️⭐️⭐️⭐️简述:自360网盘关闭后,我转而使用百度网盘(被逼无奈),或者平时找资源大多也是通过百度网盘分享的,但是百度网盘的限速是真的难顶,于是,我找到了这个Pandownload,真的好用,速度拉满官网:http://pandownload.com/ 迅雷极速版 ⭐️⭐️⭐️⭐️简述:迅雷已经是国内最大的下载商,但是也正是这个原因,没有竞争对手,那个广告,是真的多。迅雷极速版作为迅雷所有产品中最为良心的产品,广告少、页面简介明了,拥有者很多用户,即使迅雷后来砍掉了极速版,人有很多人在继续使用。下载地址:https://pan.baidu.com/s/1XstEIhCJhjYNTlOBBXZkIA来源地址:https://www.52pojie.cn/thread-737632-1-1.html 音乐类网易云音乐 ⭐️⭐️⭐️⭐️简述:好东西,不用多说,即使版权确实有点少官网:https://music.163.com/ QQ音乐 ⭐️⭐️⭐️⭐️简述:版权多(腾讯爸爸是真的财大气粗)官网:https://y.qq.com/ 开发类VS Code ⭐️⭐️⭐️⭐️简述:前端开发必备,微软良心产品官网:https://code.visualstudio.com/ Sublime ⭐️⭐️⭐️⭐️简述:轻量级,插件齐全,快捷键多,完全可以替代记事本使用官网:http://www.sublimetext.com/ IDEA(jetbrains全家桶)⭐️⭐️⭐️⭐️简述:重量级,功能齐全,Java开发首选利器官网:http://www.jetbrains.com/ 播放器唯一推荐:PotPlayer ⭐️⭐️⭐️⭐️⭐️简述:不复杂,不流氓,万能不卡顿,无广告,无弹窗、无其他强制捆绑官网:https://potplayer.daum.net/?lang=zh_CN国内地址:http://www.potplayer.org/","categories":[{"name":"工具","slug":"工具","permalink":"http://http://www.aferica.site/categories/工具/"}],"tags":[{"name":"工具","slug":"工具","permalink":"http://http://www.aferica.site/tags/工具/"},{"name":"Windows","slug":"Windows","permalink":"http://http://www.aferica.site/tags/Windows/"},{"name":"软件","slug":"软件","permalink":"http://http://www.aferica.site/tags/软件/"}]},{"title":"苹果CMS系列网站API整理","slug":"苹果CMS系列网站API整理","date":"2019-07-18T09:29:07.000Z","updated":"2019-07-18T09:56:38.725Z","comments":true,"path":"post/a362b1ac.html","link":"","permalink":"http://http://www.aferica.site/post/a362b1ac.html","excerpt":"","text":"灵感来源我一直喜欢看网络小说,之前一直使用“追书神器(之前我还写了一个追书神器接口的博客”来看小说,但是前段时间,它挂了,于是我找到了一个替代品,或者说更优秀的APP“阅读”。在使用该小说软件时,我在GitHub上找它的书源地址,找到了一个很好的整理地址,它除了小说源地址,还有视频源解析,我在研究和使用过程中,发现他的不少采集网站都是使用苹果CMS,官网:搭建的,于是我整理了一下。 使用源如上说,我主要使用的是他的满分视频源: https://moonbegonia.github.io/Source/fangyuan/fullScore.json,毕竟数量不重要,质量才最重要。我对该数据一一测试和整理,筛选出其中使用苹果CMS,并且开通了API接口的几个网址 整理数据123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407{ \"source\": [ { \"baseUrl\": \"https://www.qtmovie.com\", \"title\": \"晴天影视\", \"type\": [ { \"name\": \"电影\", \"id\": \"1\", \"minor\": [ { \"name\": \"全部\", \"id\": \"1,6,7,8,9,10,11,12,20,21,22,23,24,25,26,27,28,29,30,31,32,33\" }, { \"name\": \"动作\", \"id\": \"6\" }, { \"name\": \"喜剧\", \"id\": \"7\" }, { \"name\": \"爱情\", \"id\": \"8\" }, { \"name\": \"科幻\", \"id\": \"9\" }, { \"name\": \"恐怖\", \"id\": \"10\" }, { \"name\": \"剧情\", \"id\": \"11\" }, { \"name\": \"战争\", \"id\": \"12\" }, { \"name\": \"惊悚\", \"id\": \"20\" }, { \"name\": \"悬疑\", \"id\": \"21\" }, { \"name\": \"犯罪\", \"id\": \"22\" }, { \"name\": \"奇幻\", \"id\": \"23\" }, { \"name\": \"冒险\", \"id\": \"24\" }, { \"name\": \"动画\", \"id\": \"25\" }, { \"name\": \"武侠\", \"id\": \"26\" }, { \"name\": \"枪战\", \"id\": \"27\" }, { \"name\": \"纪录\", \"id\": \"28\" }, { \"name\": \"经典\", \"id\": \"29\" }, { \"name\": \"青春\", \"id\": \"30\" }, { \"name\": \"文艺\", \"id\": \"31\" }, { \"name\": \"古装\", \"id\": \"32\" }, { \"name\": \"历史\", \"id\": \"33\" } ] }, { \"name\": \"电视剧\", \"id\": \"2\", \"minor\": [ { \"name\": \"全部\", \"id\": \"2,13,14,15,16,41,42,43,44,45,46\" }, { \"name\": \"内地剧\", \"id\": \"13\" }, { \"name\": \"港剧\", \"id\": \"14\" }, { \"name\": \"台剧\", \"id\": \"15\" }, { \"name\": \"日剧\", \"id\": \"16\" }, { \"name\": \"韩剧\", \"id\": \"41\" }, { \"name\": \"美剧\", \"id\": \"42\" }, { \"name\": \"英剧\", \"id\": \"43\" }, { \"name\": \"泰剧\", \"id\": \"44\" }, { \"name\": \"新加坡\", \"id\": \"45\" }, { \"name\": \"其它剧\", \"id\": \"46\" } ] }, { \"name\": \"综艺\", \"id\": \"3\", \"minor\": [ { \"name\": \"全部\", \"id\": \"3\" } ] }, { \"name\": \"动漫\", \"id\": \"4\", \"minor\": [ { \"name\": \"全部\", \"id\": \"4\" } ] } ] }, { \"baseUrl\": \"http://fpx6.cn\", \"title\": \"墨语影视\", \"type\": [ { \"name\": \"电影\", \"id\": \"1\", \"minor\": [ { \"name\": \"全部\", \"id\": \"1,6,7,8,9,10,11,12\" }, { \"name\": \"动作片\", \"id\": \"6\" }, { \"name\": \"喜剧片\", \"id\": \"7\" }, { \"name\": \"爱情片\", \"id\": \"8\" }, { \"name\": \"科幻片\", \"id\": \"9\" }, { \"name\": \"恐怖片\", \"id\": \"10\" }, { \"name\": \"剧情片\", \"id\": \"11\" }, { \"name\": \"战争片\", \"id\": \"12\" } ] }, { \"name\": \"电视剧\", \"id\": \"2\", \"minor\": [ { \"name\": \"全部\", \"id\": \"2,13,14,15,16\" }, { \"name\": \"国产剧\", \"id\": \"13\" }, { \"name\": \"港台剧\", \"id\": \"14\" }, { \"name\": \"日韩剧\", \"id\": \"15\" }, { \"name\": \"欧美剧\", \"id\": \"16\" } ] }, { \"name\": \"福利\", \"id\": \"3\", \"minor\": [ { \"name\": \"全部\", \"id\": \"3\" } ] }, { \"name\": \"动漫\", \"id\": \"4\", \"minor\": [ { \"name\": \"全部\", \"id\": \"4\" } ] } ] }, { \"baseUrl\": \"http://www.qingqingyy.com\", \"title\": \"轻轻影院\", \"type\": [ { \"name\": \"电影\", \"id\": \"1\", \"minor\": [ { \"name\": \"全部\", \"id\": \"1,6,7,8,9,10,11,12\" }, { \"name\": \"动作片\", \"id\": \"6\" }, { \"name\": \"喜剧片\", \"id\": \"7\" }, { \"name\": \"爱情片\", \"id\": \"8\" }, { \"name\": \"科幻片\", \"id\": \"9\" }, { \"name\": \"恐怖片\", \"id\": \"10\" }, { \"name\": \"剧情片\", \"id\": \"11\" }, { \"name\": \"战争片\", \"id\": \"12\" } ] }, { \"name\": \"电视剧\", \"id\": \"2\", \"minor\": [ { \"name\": \"全部\", \"id\": \"2,13,14,15,16\" }, { \"name\": \"国产剧\", \"id\": \"13\" }, { \"name\": \"港台剧\", \"id\": \"14\" }, { \"name\": \"日韩剧\", \"id\": \"15\" }, { \"name\": \"欧美剧\", \"id\": \"16\" } ] }, { \"name\": \"综艺\", \"id\": \"3\", \"minor\": [ { \"name\": \"全部\", \"id\": \"3\" } ] }, { \"name\": \"动漫\", \"id\": \"4\", \"minor\": [ { \"name\": \"全部\", \"id\": \"4\" } ] } ] }, { \"baseUrl\": \"http://www.xindyy.cn\", \"title\": \"迪迪影视\", \"type\": [ { \"name\": \"电影\", \"id\": \"1\", \"minor\": [ { \"name\": \"全部\", \"id\": \"1,6,7,8,9,10,11,12\" }, { \"name\": \"动作片\", \"id\": \"6\" }, { \"name\": \"喜剧片\", \"id\": \"7\" }, { \"name\": \"爱情片\", \"id\": \"8\" }, { \"name\": \"科幻片\", \"id\": \"9\" }, { \"name\": \"恐怖片\", \"id\": \"10\" }, { \"name\": \"剧情片\", \"id\": \"11\" }, { \"name\": \"战争片\", \"id\": \"12\" } ] }, { \"name\": \"电视剧\", \"id\": \"2\", \"minor\": [ { \"name\": \"全部\", \"id\": \"2,13,14,15,16\" }, { \"name\": \"国产剧\", \"id\": \"13\" }, { \"name\": \"港台剧\", \"id\": \"14\" }, { \"name\": \"日韩剧\", \"id\": \"15\" }, { \"name\": \"欧美剧\", \"id\": \"16\" } ] }, { \"name\": \"综艺\", \"id\": \"3\", \"minor\": [ { \"name\": \"全部\", \"id\": \"3\" } ] }, { \"name\": \"动漫\", \"id\": \"4\", \"minor\": [ { \"name\": \"全部\", \"id\": \"4\" } ] } ] }, { \"baseUrl\": \"http://www.2n65.cn\", \"title\": \"VIPKU\", \"type\": [ { \"name\": \"电影\", \"id\": \"1\", \"minor\": [ { \"name\": \"全部\", \"id\": \"1,6,7,8,9,10,11,12\" }, { \"name\": \"动作片\", \"id\": \"6\" }, { \"name\": \"喜剧片\", \"id\": \"7\" }, { \"name\": \"爱情片\", \"id\": \"8\" }, { \"name\": \"科幻片\", \"id\": \"9\" }, { \"name\": \"恐怖片\", \"id\": \"10\" }, { \"name\": \"剧情片\", \"id\": \"11\" }, { \"name\": \"战争片\", \"id\": \"12\" } ] }, { \"name\": \"电视剧\", \"id\": \"2\", \"minor\": [ { \"name\": \"全部\", \"id\": \"2,13,14,15,16\" }, { \"name\": \"国产剧\", \"id\": \"13\" }, { \"name\": \"港台剧\", \"id\": \"14\" }, { \"name\": \"日韩剧\", \"id\": \"15\" }, { \"name\": \"欧美剧\", \"id\": \"16\" } ] }, { \"name\": \"综艺\", \"id\": \"3\", \"minor\": [ { \"name\": \"全部\", \"id\": \"3\" } ] }, { \"name\": \"动漫\", \"id\": \"4\", \"minor\": [ { \"name\": \"全部\", \"id\": \"4\" } ] } ] }, { \"baseUrl\": \"http://www.yunkej.cn\", \"title\": \"云客影视\", \"type\": [ { \"name\": \"电影\", \"id\": \"1\", \"minor\": [ { \"name\": \"全部\", \"id\": \"1,6,7,8,9,10,11,12\" }, { \"name\": \"动作片\", \"id\": \"6\" }, { \"name\": \"喜剧片\", \"id\": \"7\" }, { \"name\": \"爱情片\", \"id\": \"8\" }, { \"name\": \"科幻片\", \"id\": \"9\" }, { \"name\": \"恐怖片\", \"id\": \"10\" }, { \"name\": \"剧情片\", \"id\": \"11\" }, { \"name\": \"战争片\", \"id\": \"12\" } ] }, { \"name\": \"电视剧\", \"id\": \"2\", \"minor\": [ { \"name\": \"全部\", \"id\": \"2,13,14,15,16\" }, { \"name\": \"国产剧\", \"id\": \"13\" }, { \"name\": \"港台剧\", \"id\": \"14\" }, { \"name\": \"日韩剧\", \"id\": \"15\" }, { \"name\": \"欧美剧\", \"id\": \"16\" } ] }, { \"name\": \"综艺\", \"id\": \"3\", \"minor\": [ { \"name\": \"全部\", \"id\": \"3\" } ] }, { \"name\": \"动漫\", \"id\": \"4\", \"minor\": [ { \"name\": \"全部\", \"id\": \"4\" } ] } ] }, { \"baseUrl\": \"http://www.binbin95.com\", \"title\": \"彬彬影院\", \"type\": [ { \"name\": \"电影\", \"id\": \"1\", \"minor\": [ { \"name\": \"全部\", \"id\": \"1,6,7,8,9,10,11,12\" }, { \"name\": \"动作片\", \"id\": \"6\" }, { \"name\": \"喜剧片\", \"id\": \"7\" }, { \"name\": \"爱情片\", \"id\": \"8\" }, { \"name\": \"科幻片\", \"id\": \"9\" }, { \"name\": \"恐怖片\", \"id\": \"10\" }, { \"name\": \"剧情片\", \"id\": \"11\" }, { \"name\": \"战争片\", \"id\": \"12\" } ] }, { \"name\": \"电视剧\", \"id\": \"2\", \"minor\": [ { \"name\": \"全部\", \"id\": \"2,13,14,15,16\" }, { \"name\": \"国产剧\", \"id\": \"13\" }, { \"name\": \"港台剧\", \"id\": \"14\" }, { \"name\": \"日韩剧\", \"id\": \"15\" }, { \"name\": \"欧美剧\", \"id\": \"16\" } ] }, { \"name\": \"综艺\", \"id\": \"3\", \"minor\": [ { \"name\": \"全部\", \"id\": \"3\" } ] }, { \"name\": \"动漫\", \"id\": \"4\", \"minor\": [ { \"name\": \"全部\", \"id\": \"4\" } ] } ] }, { \"baseUrl\": \"http://kan.eeeul.com\", \"title\": \"会源影视\", \"type\": [ { \"name\": \"电影\", \"id\": \"1\", \"minor\": [ { \"name\": \"全部\", \"id\": \"1,6,7,8,9,10,11,12\" }, { \"name\": \"动作片\", \"id\": \"6\" }, { \"name\": \"喜剧片\", \"id\": \"7\" }, { \"name\": \"爱情片\", \"id\": \"8\" }, { \"name\": \"科幻片\", \"id\": \"9\" }, { \"name\": \"恐怖片\", \"id\": \"10\" }, { \"name\": \"剧情片\", \"id\": \"11\" }, { \"name\": \"战争片\", \"id\": \"12\" } ] }, { \"name\": \"电视剧\", \"id\": \"2\", \"minor\": [ { \"name\": \"全部\", \"id\": \"2,13,14,15,16\" }, { \"name\": \"国产剧\", \"id\": \"13\" }, { \"name\": \"港台剧\", \"id\": \"14\" }, { \"name\": \"日韩剧\", \"id\": \"15\" }, { \"name\": \"欧美剧\", \"id\": \"16\" } ] }, { \"name\": \"综艺\", \"id\": \"3\", \"minor\": [ { \"name\": \"全部\", \"id\": \"3\" } ] }, { \"name\": \"动漫\", \"id\": \"4\", \"minor\": [ { \"name\": \"全部\", \"id\": \"4\" } ] } ] }, { \"baseUrl\": \"https://m.jlszyy.cc\", \"title\": \"达达兔\", \"type\": [ { \"name\": \"电影\", \"id\": \"1\", \"minor\": [ { \"name\": \"全部\", \"id\": \"1,6,7,8,9,10,11,12\" }, { \"name\": \"动作片\", \"id\": \"6\" }, { \"name\": \"喜剧片\", \"id\": \"7\" }, { \"name\": \"爱情片\", \"id\": \"8\" }, { \"name\": \"科幻片\", \"id\": \"9\" }, { \"name\": \"恐怖片\", \"id\": \"10\" }, { \"name\": \"剧情片\", \"id\": \"11\" }, { \"name\": \"战争片\", \"id\": \"12\" } ] }, { \"name\": \"电视剧\", \"id\": \"2\", \"minor\": [ { \"name\": \"全部\", \"id\": \"2,13,14,15,16\" }, { \"name\": \"国产剧\", \"id\": \"13\" }, { \"name\": \"港台剧\", \"id\": \"14\" }, { \"name\": \"日韩剧\", \"id\": \"15\" }, { \"name\": \"欧美剧\", \"id\": \"16\" } ] }, { \"name\": \"综艺\", \"id\": \"3\", \"minor\": [ { \"name\": \"全部\", \"id\": \"3\" } ] }, { \"name\": \"动漫\", \"id\": \"4\", \"minor\": [ { \"name\": \"全部\", \"id\": \"4\" } ] } ] }, ], \"list\": { \"mainUrl\": \"/api.php/provide/vod/?ac=list\", \"type\": \"t\", \"page\": \"pg\", \"searchKey\": \"wd\", \"hours\": \"h\" }, \"detail\": { \"mainUrl\": \"/api.php/provide/vod/?ac=detail\", \"ids\": \"ids\", \"type\": \"t\", \"page\": \"pg\", \"hours\": \"h\" }}; 接口使用接口分为两个,分别是获取列表和获取详情 列表接口url:网址地址 + /api.php/provide/vod/?ac=list例:https://www.qtmovie.com/api.php/provide/vod/?ac=list参数说明(皆可以不传) t: 影片类型 pg: 页数 searchKey:搜索关键词 hours:最近多少小时内 结果:12345678910111213141516171819202122{ \"code\": 1, \"msg\": \"数据列表\", \"page\": 1, \"pagecount\": 4636, \"limit\": \"20\", \"total\": 92718, \"list\": [ { \"vod_id\": 94393, \"vod_name\": \"以爱为铭\", \"type_id\": 4, \"type_name\": \"动漫\", \"vod_en\": \"yiaiweiming\", \"vod_time\": \"2019-07-18 15:45:58\", \"vod_remarks\": \"更新到06集\", \"vod_play_from\": \"zuidam3u8\" }, // ... 更多 ], \"class\": [] // 影片分类 } 详情接口url:网址地址 + /api.php/provide/vod/?ac=detail例:https://www.qtmovie.com/api.php/provide/vod/?ac=detail参数说明(皆可以不传) ids: 影片id,多个使用,隔开 t: 影片类型 pg: 页数 hours:最近多少小时内 结果:12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091{ \"code\": 1, \"msg\": \"数据列表\", \"page\": 1, \"pagecount\": 1, \"limit\": \"20\", \"total\": 1, \"list\": [ { \"vod_id\": 94393, \"type_id\": 4, \"type_id_1\": 0, \"group_id\": 0, \"vod_name\": \"以爱为铭\", \"vod_sub\": \"\", \"vod_en\": \"yiaiweiming\", \"vod_status\": 1, \"vod_letter\": \"Y\", \"vod_color\": \"\", \"vod_tag\": \"我知道我很帅,可你也不用这样看着我,我会很害羞的,只要戴上去了,就永远也摘不下来。,100万,是你的上限!\", \"vod_class\": \"动漫\", \"vod_pic\": \"http://img.maccms.com/upload/vod/20190715-1/ea439cfcfd80bc3aa517e7c4104ed845.jpg\", \"vod_pic_thumb\": \"\", \"vod_pic_slide\": \"\", \"vod_actor\": \"内详\", \"vod_director\": \"未知\", \"vod_writer\": \"\", \"vod_behind\": \"\", \"vod_blurb\": \" “100万,是你的上限!” “我知道我很帅,可你也不用这样看着我,我会很害羞的” “只要戴上去了,就永远也摘不下来。” 他给过她极致的宠爱,也给过囚牢般的痛楚,这段错乱的人生,找到对的人……\", \"vod_remarks\": \"更新到06集\", \"vod_pubdate\": \"\", \"vod_total\": 0, \"vod_serial\": \"0\", \"vod_tv\": \"\", \"vod_weekday\": \"\", \"vod_area\": \"大陆\", \"vod_lang\": \"国语\", \"vod_year\": \"2019\", \"vod_version\": \"\", \"vod_state\": \"\", \"vod_author\": \"\", \"vod_jumpurl\": \"\", \"vod_tpl\": \"\", \"vod_tpl_play\": \"\", \"vod_tpl_down\": \"\", \"vod_isend\": 1, \"vod_lock\": 0, \"vod_level\": 0, \"vod_copyright\": 0, \"vod_points\": 0, \"vod_points_play\": 0, \"vod_points_down\": 0, \"vod_hits\": 53, \"vod_hits_day\": 520, \"vod_hits_week\": 612, \"vod_hits_month\": 873, \"vod_duration\": \"\", \"vod_up\": 420, \"vod_down\": 636, \"vod_score\": \"9.0\", \"vod_score_all\": 7524, \"vod_score_num\": 836, \"vod_time\": \"2019-07-18 15:45:58\", \"vod_time_add\": 1563158717, \"vod_time_hits\": 0, \"vod_time_make\": 0, \"vod_trysee\": 0, \"vod_douban_id\": 0, \"vod_douban_score\": \"0.0\", \"vod_reurl\": \"\", \"vod_rel_vod\": \"\", \"vod_rel_art\": \"\", \"vod_pwd\": \"\", \"vod_pwd_url\": \"\", \"vod_pwd_play\": \"\", \"vod_pwd_play_url\": \"\", \"vod_pwd_down\": \"\", \"vod_pwd_down_url\": \"\", \"vod_content\": \" “100万,是你的上限!” “我知道我很帅,可你也不用这样看着我,我会很害羞的” “只要戴上去了,就永远也摘不下来。” 他给过她极致的宠爱,也给过囚牢般的痛楚,这段错乱的人生,找到对的人……\", \"vod_play_from\": \"zuidam3u8\", \"vod_play_server\": \"no\", \"vod_play_note\": \"\", \"vod_play_url\": \"第01集$https://wuji.zhulong-zuida.com/20190715/1844_b533813a/index.m3u8#第02集$https://wuji.zhulong-zuida.com/20190715/1843_a63a36b3/index.m3u8#第03集$https://wuji.zhulong-zuida.com/20190715/1842_f944af87/index.m3u8#第04集$https://wuji.zhulong-zuida.com/20190715/1841_ac4ede49/index.m3u8#第05集$https://wuji.zhulong-zuida.com/20190715/1840_36eb3d28/index.m3u8#第06集$https://bili.meijuzuida.com/20190718/20654_ddedd75b/index.m3u8\", \"vod_down_from\": \"\", \"vod_down_server\": \"\", \"vod_down_note\": \"\", \"vod_down_url\": \"\", \"type_name\": \"动漫\" } ]}","categories":[{"name":"API","slug":"API","permalink":"http://http://www.aferica.site/categories/API/"}],"tags":[{"name":"API","slug":"API","permalink":"http://http://www.aferica.site/tags/API/"},{"name":"苹果CMS","slug":"苹果CMS","permalink":"http://http://www.aferica.site/tags/苹果CMS/"},{"name":"视频采集","slug":"视频采集","permalink":"http://http://www.aferica.site/tags/视频采集/"}]},{"title":"Flutter学习(五):网络请求封装优化","slug":"Flutter学习(五):网络请求封装优化","date":"2019-07-10T02:57:37.000Z","updated":"2019-07-10T06:48:54.834Z","comments":true,"path":"post/913cd901.html","link":"","permalink":"http://http://www.aferica.site/post/913cd901.html","excerpt":"","text":"在之前的文章Flutter学习(三):网络请求Dio模块使用中,我简单的介绍了Dio模块的使用和封装,比较浅显,使用时有很多不足和重复,在本文中,我将对封装进行进一步的优化。 常用功能配置设置网络请求的拦截器在日常开发中使用非常广泛,例如:添加统一认证Header,判断登录状态已跳转登录页简单实现: 1.创建Dio对象推荐在一个工具文件中定义和初始化Dio对象,同时还可以定制Get、Post123456789101112131415161718192021/** * utils/request.dart * 初始化和基本封装 */import 'package:flutter/material.dart';import 'package:dio/dio.dart';// 自定义的网络请求加载弹框组件import 'components/Dialog.dart';// 设置统一请求连接时间和超时时间BaseOptions options = new BaseOptions( connectTimeout: 5000, receiveTimeout: 10000, responseType: ResponseType.plain);Dio dio = new Dio(options);class Request { // ... 自定义封装,详情查看第3步} 2.添加设置全局拦截器1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768/** * main.dart * 项目入口文件 */import 'package:flutter/material.dart';import 'package:fluro/fluro.dart';import 'package:dio/dio.dart';import 'package:fluttertoast/fluttertoast.dart';import 'utils/request.dart';import 'utils/route.dart';void main() { // 添加路由 final router = new Router(); Routes.configureRoutes(router); Routes.router = router; // 添加dio拦截器 dio.interceptors.add(InterceptorsWrapper( // 在请求被发送之前做一些事情 onRequest: (RequestOptions options) async { print('请求地址:' + options.uri.toString()); /** * 添加统一认证 */ const token = ''; // 这里token保存和获取可以使用SharedPreferences模块 if(token == '') { // 处理未登录情况,如跳转到登录页 Fluttertoast.showToast(msg: '请登录后使用', backgroundColor: Colors.black54, fontSize: 14.0); // 结束请求 errMsg可以为任何类型,例如字符串、数字、Map等 return dio.reject(errMsg); } else { // 使用jwt认证 options.headers['Authorization'] = 'Bearer ' + token; // 或者添加token options.headers['token'] = token; // continue return options; } onResponse: (Response response) async { print(response.data.toString()); // 对返回数据JSON数据处理 // 例如`[{\"\":\"\"},{\"\":\"\"},{\"\":\"\"}]` // 需要使用`{}`处理后才可以转为Map String tempRes = response.data.toString(); if(tempRes[0] == '[') { tempRes = '{\"reslut\":' + tempRes + '}'; } Map<String, dynamic> result = json.decode(tempRes.toString()); response.data = result; return response; }, onError: (DioError e) { if(e.type == DioErrorType.CONNECT_TIMEOUT || e.type == DioErrorType.RECEIVE_TIMEOUT || e.type == DioErrorType.SEND_TIMEOUT) { Fluttertoast.showToast(msg: '网络请求超时,请检查网络后重试', backgroundColor: Colors.black54, fontSize: 12.0); } if(e.type == DioErrorType.CANCEL) { Fluttertoast.showToast(msg: '用户取消请求', backgroundColor: Colors.black54, fontSize: 12.0); } return e; } )); runApp(MyApp());}class MyApp extends StatelessWidget { // 省略} 3.请求方法封装12345678910111213141516171819202122232425262728293031323334/** * utils/request.dart * 初始化和基本封装 */... // 续接第1步class Request { // 自定义封装 已get方法为例 /// /// @require url 请求地址 /// @require context 请求页BuildContext对象 /// showLoading 是否显示加载提示框 /// closeLoading 是否关闭加载提示框 /// 这两个通常配合使用 /// 当连续请求,如首页加载过多信息时,可以通过设置第一次显示提示框,不关闭 /// 最后一次只关闭,不显示,中间不显示不关闭来避免多次闪烁的问题 /// static Future<Map<String, dynamic>> get(String url, BuildContext context,{ bool showLoading = true, bool closeLoading = true}) async { if (showLoading) { showDialog<Null>( context: context, builder: (_) => LoadingDialog() ); } Response res = await dio.get(url); if (closeLoading) { Navigator.pop(context); } if (res.statusCode != 200) { return {}; } return res.data; }} 4.使用示例123456789101112131415161718192021222324252627// 引入工具包import 'utils/request.dart';// 在initState方法中调用...class xxxState extends State<xxx> { ... @override void initState() { // TODO: implement initState super.initState(); // 解决inheritFromWidgetOfExactType(_LocalizationsScope) or inheritFromElement() was called before VideoInfoState.initState() completed报错 WidgetsBinding.instance.addPostFrameCallback((_){ getInfo(); }); } getInfo () { String url = 'xxx'; Map<String, dynamic> infoMap = await Request.get(url, context); } ...}... 使用效果 注意:inheritFromWidgetOfExactType(_LocalizationsScope) or inheritFromElement() was called before VideoInfoState.initState() completed报错在使用时,如果出现inheritFromWidgetOfExactType(_LocalizationsScope) or inheritFromElement() was called before VideoInfoState.initState() completed报错,如下图:查看自己initState中调用网络请求方法是否使用WidgetsBinding.instance.addPostFrameCallback((_){}处理","categories":[{"name":"Flutter","slug":"Flutter","permalink":"http://http://www.aferica.site/categories/Flutter/"}],"tags":[{"name":"Flutter","slug":"Flutter","permalink":"http://http://www.aferica.site/tags/Flutter/"},{"name":"移动开发","slug":"移动开发","permalink":"http://http://www.aferica.site/tags/移动开发/"},{"name":"网络请求","slug":"网络请求","permalink":"http://http://www.aferica.site/tags/网络请求/"},{"name":"Http封装","slug":"Http封装","permalink":"http://http://www.aferica.site/tags/Http封装/"}]},{"title":"Flutter学习(四):图片组件cached_network_image介绍","slug":"Flutter学习(四):图片组件cached-network-image介绍","date":"2019-07-01T08:59:21.000Z","updated":"2019-07-30T08:13:37.669Z","comments":true,"path":"post/a9dab570.html","link":"","permalink":"http://http://www.aferica.site/post/a9dab570.html","excerpt":"","text":"图片是一个APP中必不可少的部分,缺少图片的APP会显得格外的单调乏味。但是同样的,图片也是APP最占据资源和影响体验的组件之一,加载缓慢、重复加载、加载失败、加载完成后导致页面布局发生变化同样会导致用户体验极差。Flutter虽然自带了Image,但是功能十分简单,不足以满足日常的使用,于是我找到了cached_network_image来满足需求。 官网Pub.dev地址:https://pub.flutter-io.cn/packages/cached_network_imageGitHub地址:https://github.com/renefloor/flutter_cached_network_image 优势 使用简单 支持默认图片/加载图片、动图设置(placeholder) 支持淡入淡出动画显示 支持错误图片设置(errorWidget) 支持缓存,减少重复请求 API文档英文文档:https://pub.flutter-io.cn/documentation/cached_network_image/latest/cached_network_image/cached_network_image-library.html 构造函数12345678910111213141516171819202122CachedNetworkImage({ Key key, @required this.imageUrl, this.imageBuilder, this.placeholder, this.errorWidget, this.fadeOutDuration: const Duration(milliseconds: 300), this.fadeOutCurve: Curves.easeOut, this.fadeInDuration: const Duration(milliseconds: 700), this.fadeInCurve: Curves.easeIn, this.width, this.height, this.fit, this.alignment: Alignment.center, this.repeat: ImageRepeat.noRepeat, this.matchTextDirection: false, this.httpHeaders, this.cacheManager, this.useOldImageOnUrlChange: false, this.color, this.colorBlendMode,}) 属性解析 imageUrl: 图片地址,必须 imageBuilder: 可选构建器,自定义图像的显示。 placeholder: 初始控件,在加载图片时显示,如加载动画,常用 errorWidget: 图片加载失败显示 fadeOutDuration/fadeOutCurve: 淡出动画效果设置 fadeInDuration/fadeInCurve: 淡入动画效果设置 width: 图片宽度 height: 图片高度度 fit: 填充方式 repeat: 是否及如何重复背景图像,类似于CSS中的background-repeat alignment: 对齐方式 httpHeaders: 图片请求Header设置,可用于反防盗链使用 使用Demo1234567891011121314151617181920new CachedNetworkImage( // 设置图片宽度为屏幕宽度 width: MediaQuery.of(context).size.width, // 设置根据宽度计算高度 height: MediaQuery.of(context).size.width / 40 * 27, // 图片地址 imageUrl: 'xxx', // 填充方式为cover fit: BoxFit.cover, // 加载样式为IOS的加载,居中显示 placeholder: (context, url) => new Container( child: Center( child: new CupertinoActivityIndicator(), ), ), // 加载失败后显示自定义的404图片 errorWidget: (context, url, error) => new Container( child: new Image.asset('static/images/404w.png', height: 100, width: 100,), ),),","categories":[{"name":"Flutter","slug":"Flutter","permalink":"http://http://www.aferica.site/categories/Flutter/"}],"tags":[{"name":"Flutter","slug":"Flutter","permalink":"http://http://www.aferica.site/tags/Flutter/"},{"name":"移动开发","slug":"移动开发","permalink":"http://http://www.aferica.site/tags/移动开发/"},{"name":"图片","slug":"图片","permalink":"http://http://www.aferica.site/tags/图片/"},{"name":"cached_network_image","slug":"cached-network-image","permalink":"http://http://www.aferica.site/tags/cached-network-image/"}]},{"title":"前端开发素材网站推荐","slug":"前端开发素材网站推荐","date":"2019-06-26T06:22:59.000Z","updated":"2019-06-26T09:41:59.621Z","comments":true,"path":"post/3c21d7d9.html","link":"","permalink":"http://http://www.aferica.site/post/3c21d7d9.html","excerpt":"","text":"作为一个前端开发者,很多时候开发不是问题,但是设计页面往往是一个难题,尤其是没有设计稿的时候。图标、配色、图片、布局等等,总是根绝自己的页面不好看,不规范,却又不知道怎么修改。下面是我在日常开发过程中积累的一些好的素材,可供参考。 图标类唯一推荐iconfont-阿里巴巴矢量图标库 ⭐️⭐️⭐️⭐️⭐️ 地址:https://www.iconfont.cn/阿里出品,图标齐全,图标库众多,使用方便,兼容性好,良心推荐。有这一个,图标再也不是问题 配色方案Color Hunt ⭐️⭐️⭐️⭐️⭐️ 地址:https://colorhunt.co/ 优点: 多种配色方案可供选择 4色一套,基本满足整体配色。缺点: 访问可能需要科学上网,可能有点慢 中国色 ⭐️⭐️⭐️⭐️ 地址:http://zhongguose.com/ 优点: 色彩颜色符合国人审美 色彩多,选择多缺点: 自我感觉颜色查看并不直观,需要依次点击才可以确认 渐变色 ⭐️⭐️⭐️⭐️ 地址:https://webgradients.com/ 优点: 纯CSS实现,兼容性较好 色彩教多,选择多缺点: 颜色多为两种颜色,少有多色,但基本满足需求 CSS实现,Android、IOS等不支持 背景图片推荐Pixabay ⭐️⭐️⭐️⭐️ 地址:https://pixabay.com/ Bing壁纸 ⭐️⭐️⭐️⭐️ 地址:https://github.com/xCss/bing/tree/v1.0.0 其它站酷 ⭐️⭐️⭐️⭐️ 地址:https://www.zcool.com.cn/ UI中国 ⭐️⭐️⭐️ 地址:https://www.ui.cn/ RGB颜色值转换成十六进制颜色码 ⭐️⭐️⭐️⭐️ 地址:https://www.sioe.cn/yingyong/yanse-rgb-16/","categories":[{"name":"前端","slug":"前端","permalink":"http://http://www.aferica.site/categories/前端/"},{"name":"素材","slug":"前端/素材","permalink":"http://http://www.aferica.site/categories/前端/素材/"}],"tags":[{"name":"素材","slug":"素材","permalink":"http://http://www.aferica.site/tags/素材/"},{"name":"配色方案","slug":"配色方案","permalink":"http://http://www.aferica.site/tags/配色方案/"},{"name":"背景图","slug":"背景图","permalink":"http://http://www.aferica.site/tags/背景图/"},{"name":"图标库","slug":"图标库","permalink":"http://http://www.aferica.site/tags/图标库/"},{"name":"图片取色","slug":"图片取色","permalink":"http://http://www.aferica.site/tags/图片取色/"}]},{"title":"VsCode配置Vue模板","slug":"VsCode配置Vue模板","date":"2019-06-20T03:46:13.000Z","updated":"2019-06-20T06:15:17.017Z","comments":true,"path":"post/2a234aa1.html","link":"","permalink":"http://http://www.aferica.site/post/2a234aa1.html","excerpt":"","text":"VS Code拥有很多特别适合和方便的功能,自定义文件模板就是其中之一,本文中主要记录Vue的模板 创建模板步骤 点击VS Code左下角设置按钮,选择用户代码片段 选择新建全局代码片段,输入名称,例如vue 编辑文件即可 Vue页面代码123456789101112131415161718192021222324252627282930313233{ \"Print to console\": { \"prefix\": \"vue\", \"body\": [ \"<template>\", \" <div id=\\\"page\\\"></div>\", \"</template>\", \"\", \"<script>\", \"export default {\", \" name: 'page',\", \" data () {\", \" return {\", \" }\", \" },\", \"\", \" components: {},\", \"\", \" computed: {},\", \"\", \" mounted () {},\", \"\", \" methods: {}\", \"}\", \"\", \"</script>\", \"<style scoped>\", \"</style>\", \"\" ], \"description\": \"vue模板\" }} Vue组件代码12345678910111213141516171819202122232425262728293031323334353637{ \"Print to console\": { \"prefix\": \"vue-component\", \"body\": [ \"<template>\", \" <div id=\\\"component\\\"></div>\", \"</template>\", \"\", \"<script>\", \"export default {\", \" name: 'component',\", \" data () {\", \" return {\", \" }\", \" },\", \" props: {\", \" value: {\", \" type: Object,\", \" default () {\", \" return {}\", \" }\", \" }\", \" },\", \"\", \" computed: {},\", \"\", \" methods: {}\", \"}\", \"\", \"</script>\", \"<style scoped>\", \"</style>\", \"\" ], \"description\": \"vue组件模板\" }}","categories":[{"name":"前端","slug":"前端","permalink":"http://http://www.aferica.site/categories/前端/"},{"name":"Vue","slug":"前端/Vue","permalink":"http://http://www.aferica.site/categories/前端/Vue/"}],"tags":[{"name":"工具","slug":"工具","permalink":"http://http://www.aferica.site/tags/工具/"},{"name":"Vue","slug":"Vue","permalink":"http://http://www.aferica.site/tags/Vue/"},{"name":"VS Code","slug":"VS-Code","permalink":"http://http://www.aferica.site/tags/VS-Code/"}]},{"title":"Ubuntu使用遇到问题(一)","slug":"Ubuntu使用遇到问题(一)","date":"2019-06-11T03:53:38.000Z","updated":"2019-06-12T01:31:10.866Z","comments":true,"path":"post/9a314a5.html","link":"","permalink":"http://http://www.aferica.site/post/9a314a5.html","excerpt":"","text":"我在阿里云通过学生优惠(之前是需要学生认证才行,比较麻烦,后来应该是去年,修改为只要24岁以下都认为是学生),购买了一条云服务器,经常在上面测试使用,在使用中,遇到了一些问题,记录保存。 Rudy使用安装可以直接安装1sudo apt-get install rudy 默认安装版本经常不是最新版本 安装高版本添加PPA源12sudo add-apt-repository ppa:brightbox/ruby-ngsudo apt-get update 安装新版本123# 如果有旧版本需要先删除sudo apt-get purge --auto-remove rubysudo apt-get install ruby2.6 ruby2.6-dev 执行命令提示文件不存在出现该问题,大部分是因为执行命令文件没有在/usr/bin中解决方法:创建软连接1ln -s /usr/local/bin/bundle /usr/bin/bundle","categories":[{"name":"Ubuntu","slug":"Ubuntu","permalink":"http://http://www.aferica.site/categories/Ubuntu/"}],"tags":[{"name":"Ubuntu","slug":"Ubuntu","permalink":"http://http://www.aferica.site/tags/Ubuntu/"},{"name":"Rudy","slug":"Rudy","permalink":"http://http://www.aferica.site/tags/Rudy/"},{"name":"bundle","slug":"bundle","permalink":"http://http://www.aferica.site/tags/bundle/"}]},{"title":"写文章博客必备利器————PicGo","slug":"写文章博客必备利器————PicGo","date":"2019-06-05T07:29:42.000Z","updated":"2019-06-05T08:26:40.934Z","comments":true,"path":"post/d4ae078f.html","link":"","permalink":"http://http://www.aferica.site/post/d4ae078f.html","excerpt":"","text":"最为一名程序员,写文章、博客或是随笔似乎已成为一项必备技能,毕竟需要记忆和学习的东西太多了,而且经常会遇到一些稀奇古怪的问题,当你千辛万苦的解决后,本着开源精神,记录下来,发个博客,无私奉献(成功装逼),岂是一个爽字了得?而在写文章的时候,必不可少的需要添加一些截图或是其他来源图片来更容易的说明,毕竟没图就没有公信力。这时候,一个快捷强大的图片上传工具必不可少,下面诚心推荐————PicGo 原作地址PC软件官网官方文档地址GitHub地址picgo的VSCode版 简介复制粘贴的事,我就不做了,官方文档里都说的很明白主要说一下他的优点: 支持多图床 配置简单 操作简单,使用快捷键一键上传 VSCode + picgo + 阿里云OSSVSCode安装picgo插件安装VSCode插件市场搜索picgo,点击安装,如下图 配置更多配置信息可查看官方文档地址打开VSCode配置文件settings.json,添加以下配置1234567891011121314// 其他配置\"picgo\": { \"picBed\": { \"uploader\": \"aliyun\", // 当前使用图床 \"current\": \"aliyun\", // 当前使用图床 作用与picBed.uploader一致,主要是为了兼容PicGo的electron版本而留下的配置。未来有可能抛弃。 \"aliyun\": { // 阿里云OSS配置 \"accessKeyId\": \"**************\", \"accessKeySecret\": \"**************\", \"bucket\": \"**************\", // 存储空间名 \"area\": \"**************\", // 存储区域代号 \"path\": \"markdown/\" // 自定义存储路径文件所在位置 } },}, 使用快捷键 OS 从剪辑版上传(截图,复制图片,主要使用) 从文件夹上传 从输入框上传(很少用到) Windows/Unix Ctrl + Alt + U Ctrl + Alt + E Ctrl + Alt + O OsX Cmd + Opt + U Cmd + Opt + E Cmd + Opt + O 阿里云OSS登录阿里云控制台地址使用淘宝、支付宝账号即可 开通对象存储OSS 新建Bucket 查看accessKeyId和accessKeySecret","categories":[{"name":"工具","slug":"工具","permalink":"http://http://www.aferica.site/categories/工具/"}],"tags":[{"name":"工具","slug":"工具","permalink":"http://http://www.aferica.site/tags/工具/"},{"name":"VS Code","slug":"VS-Code","permalink":"http://http://www.aferica.site/tags/VS-Code/"},{"name":"PicGo","slug":"PicGo","permalink":"http://http://www.aferica.site/tags/PicGo/"}]},{"title":"Flutter学习(三):网络请求Dio模块使用","slug":"Flutter学习(三):网络请求Dio模块使用","date":"2019-06-03T08:59:21.000Z","updated":"2019-06-28T07:09:05.462Z","comments":true,"path":"post/3b0ed757.html","link":"","permalink":"http://http://www.aferica.site/post/3b0ed757.html","excerpt":"","text":"当我们使用或者制作一个APP时,数据请求验证无疑是最为关键的部分。Flutter自身带有Http模块以用于数据请求,但是过于简单,通常不能满足我们的需求。 简介dio是一个强大的Dart Http请求库,支持Restful API、FormData、拦截器、请求取消、Cookie管理、文件上传/下载、超时、自定义适配器等…官方Github地址中文文档文档比较详细,我就不重复了,下面我主要介绍基本封装 使用封装Get请求是使用最为频繁的请求方式,我们以Get为例1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465import 'package:flutter/material.dart';import 'dart:convert';import 'dart:async';// 使用fluttertoast来处理一些报错的toast提示信息import 'package:fluttertoast/fluttertoast.dart';import 'package:dio/dio.dart';// 使用shared_preferences来保存登录状态import 'package:shared_preferences/shared_preferences.dart';// 初始化final Dio dio = new Dio();class Request { static Future<Map<String, dynamic>> get(String url, { Map<String, String> params }) async { print(url); Map<String, dynamic> result = new Map(); // shared_preferences初始化 SharedPreferences prefs = await SharedPreferences.getInstance(); // 获取本地保存的token(用于身份验证) // 如果不存在就返回'' String token = prefs.getString('token') ?? ''; if(token == '') { // 未登录 返回 Fluttertoast.showToast(msg: '请登录后使用', backgroundColor: Colors.black54, fontSize: 14.0); } else { try { Response res = await dio.get( url, queryParameters: params, options: new Options( // 返回字符串 // 由于Dart不能像JS一样直接使用JSON,需要转换为Map对象 // 所以对于返回值为JSON格式数据的接口推荐返回String // 以便于接下来使用`dart:convert`将String转为Map responseType: ResponseType.plain, // JWT接口验证 吐过不需要可省略 headers: { 'Authorization': 'Bearer ' + token } ) ); String tempRes = res.toString(); // 如果返回数据是JSON数据 // 例如`[{\"\":\"\"},{\"\":\"\"},{\"\":\"\"}]` // 需要使用`{}`处理后才可以转为Map if(tempRes[0] == '[') { tempRes = '{\"reslut\":' + tempRes + '}'; } result = json.decode(tempRes.toString()); } catch (e) { // 网络异常统一处理 result = null; Fluttertoast.showToast(msg: '网络请求错误,请重试', backgroundColor: Colors.black54, fontSize: 14.0); }// 如果接口数据格式相同,如使用ok字段返回请求是否成功// 可添加 数据统一处理 // if (!result['ok']) {// Fluttertoast.showToast(msg: result['msg'], backgroundColor: Colors.black54, fontSize: 14.0);// result = null;// }// } return result; }}","categories":[{"name":"Flutter","slug":"Flutter","permalink":"http://http://www.aferica.site/categories/Flutter/"}],"tags":[{"name":"Flutter","slug":"Flutter","permalink":"http://http://www.aferica.site/tags/Flutter/"},{"name":"移动开发","slug":"移动开发","permalink":"http://http://www.aferica.site/tags/移动开发/"},{"name":"网络请求","slug":"网络请求","permalink":"http://http://www.aferica.site/tags/网络请求/"},{"name":"Http封装","slug":"Http封装","permalink":"http://http://www.aferica.site/tags/Http封装/"}]},{"title":"Flutter学习(二):常用布局控件介绍","slug":"Flutter学习(二):常用控件介绍","date":"2019-05-31T06:05:46.000Z","updated":"2019-06-28T07:08:52.311Z","comments":true,"path":"post/b534519.html","link":"","permalink":"http://http://www.aferica.site/post/b534519.html","excerpt":"","text":"在上一篇博文中,我简单的介绍了一些Flutter的知识和优势以及环境配置问题,在本篇博文中,我主要介绍一下常用到的几种Flutter常用布局控件和使用方法。首先,我们先来一张Flutter基本空间继承关系图: Container本段介绍来自Flutter 布局(一)- Container详解Container是Flutter最常使用的布局控件之一 使用场景 需要设置间隔(这种情况下,如果只是单纯的间隔,也可以通过Padding来实现); 需要设置背景色; 需要设置圆角或者边框的时候(ClipRRect也可以实现圆角效果); 需要对齐(Align也可以实现); 需要设置背景图片的时候(也可以使用Stack实现) 构造函数1234567891011121314Container({ Key key, this.alignment, this.padding, Color color, Decoration decoration, this.foregroundDecoration, double width, double height, BoxConstraints constraints, this.margin, this.transform, this.child,}) 属性解析 key:Container唯一标识符,用于查找更新。 alignment:控制child的对齐方式,如果container或者container父节点尺寸大于child的尺寸,这个属性设置会起作用,有很多种对齐方式。 padding:decoration内部的空白区域,如果有child的话,child位于padding内部。padding与margin的不同之处在于,padding是包含在content内,而margin则是外部边界,设置点击事件的话,padding区域会响应,而margin区域不会响应。 color:用来设置container背景色,如果foregroundDecoration设置的话,可能会遮盖color效果。 decoration:绘制在child后面的装饰,设置了decoration的话,就不能设置color属性,否则会报错,此时应该在decoration中进行颜色的设置。 foregroundDecoration:绘制在child前面的装饰。 width:container的宽度,设置为double.infinity可以强制在宽度上撑满,不设置,则根据child和父节点两者一起布局。 height:container的高度,设置为double.infinity可以强制在高度上撑满。 constraints:添加到child上额外的约束条件。 margin:围绕在decoration和child之外的空白区域,不属于内容区域。 transform:设置container的变换矩阵,类型为Matrix4。 child:container中的内容widget。 简单示例12345678910111213141516171819new Container( constraints: new BoxConstraints.expand( height:Theme.of(context).textTheme.display1.fontSize * 1.1 + 200.0, ), decoration: new BoxDecoration( border: new Border.all(width: 2.0, color: Colors.red), color: Colors.grey, borderRadius: new BorderRadius.all(new Radius.circular(20.0)), image: new DecorationImage( image: new NetworkImage('http://h.hiphotos.baidu.com/zhidao/wh%3D450%2C600/sign=0d023672312ac65c67506e77cec29e27/9f2f070828381f30dea167bbad014c086e06f06c.jpg'), centerSlice: new Rect.fromLTRB(270.0, 180.0, 1360.0, 730.0), ), ), padding: const EdgeInsets.all(8.0), alignment: Alignment.center, child: new Text('Hello World', style: Theme.of(context).textTheme.display1.copyWith(color: Colors.black)), transform: new Matrix4.rotationZ(0.3),) Row和ColumnRow、Column两个基本相同,只有一个是横向,一个是纵向布局的区别,所以我们以Row为例来介绍说明。 使用场景 需要横向(纵向)排列,如标签展示 网格布局(GridView也可以实现) 构造函数12345678910Row({ Key key, MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start, MainAxisSize mainAxisSize = MainAxisSize.max, CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center, TextDirection textDirection, VerticalDirection verticalDirection = VerticalDirection.down, TextBaseline textBaseline, List<Widget> children = const <Widget>[],}) 属性解析 key:Flutter控件(Widget)唯一标识符,用于查找更新。 mainAxisAlignment:子元素对齐方式,MainAxisAlignment对象,类似于css中的justify-content和align-content, 有六种对齐方式:start开始(左侧或顶部)对齐end开始(右侧或底部)对齐center居中对齐spaceBetween子元素之间留有空白,但第一个元素之前和最后一个元素之后不留空白,类似于css中space-betweenspaceAround子元素之间留有空白,第一个元素之前和最后一个元素之后留一半的空白,类似于css中space-aroundspaceEvenly子元素之间留有空白,第一个元素之前和最后一个元素之后留相等的空白,类似于css中space-around mainAxisSize:主方向大小,有min和max两个值可选 crossAxisAlignment:子元素在交叉轴方向的对齐方式 verticalDirection:定义了子元素摆放顺序,默认是down,即从左到右(从上到下),可选还有up,即从右到左(从下到上) 简单示例上面三图中的追书人数和读者留存率行实现:12345678910Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisSize: MainAxisSize.max, // 默认即为max,可不写 children: <Widget>[ Text('追书人数:', style: TextStyle(fontSize: 12.0,height: 1.5),), Text(latelyFollower, style: TextStyle(fontSize: 13.0, color: Colors.pink,height: 1.5),), Text('读者留存率:', style: TextStyle(fontSize: 12.0,height: 1.5)), Text(retentionRatio, style: TextStyle(fontSize: 13.0, color: Colors.pink,height: 1.5),) ],) ScaffoldScaffold可以说的上是Flutter中基本的页面布局 使用场景 几乎所有页面都可以使用构造函数12345678910111213141516171819Scaffold({ Key key, this.appBar, this.body, this.floatingActionButton, this.floatingActionButtonLocation, this.floatingActionButtonAnimator, this.persistentFooterButtons, this.drawer, this.endDrawer, this.bottomNavigationBar, this.bottomSheet, this.backgroundColor, this.resizeToAvoidBottomPadding, this.resizeToAvoidBottomInset, this.primary = true, this.drawerDragStartBehavior = DragStartBehavior.start, this.extendBody = false,}) 属性解析 key:Flutter控件(Widget)唯一标识符,用于查找更新。 appBar: 标题栏,详见后续介绍 body:页面内容 floatingActionButton:固定页面之上的悬浮按钮,诸如返回顶部、新增按钮都推荐使用 floatingActionButtonLocation:顾名思义,悬浮按钮位置 floatingActionButtonAnimator: persistentFooterButtons:固定在页面底部,例如微信、QQ底部的聊天框 drawer:左侧抽屉 endDrawer:右侧抽屉,注意:如果在标题栏AppBar中设置有actions,右侧添加的操作按钮会将抽屉的默认打开按钮覆盖,需要自己实现打开抽屉 bottomNavigationBar:App常用底部导航栏 backgroundColor:内容的背景颜色,默认使用的是 ThemeData.scaffoldBackgroundColor 的值 resizeToAvoidBottomPadding:控制界面内容 body 是否重新布局来避免底部被覆盖了,比如当键盘显示的时候,重新布局避免被键盘盖住内容。默认值为 true","categories":[{"name":"Flutter","slug":"Flutter","permalink":"http://http://www.aferica.site/categories/Flutter/"}],"tags":[{"name":"Flutter","slug":"Flutter","permalink":"http://http://www.aferica.site/tags/Flutter/"},{"name":"移动开发","slug":"移动开发","permalink":"http://http://www.aferica.site/tags/移动开发/"}]},{"title":"Flutter学习(一):环境安装遇到问题和基本介绍","slug":"Flutter学习(一):环境安装遇到问题","date":"2019-05-29T16:06:56.000Z","updated":"2019-07-30T08:07:57.711Z","comments":true,"path":"post/890a9b8e.html","link":"","permalink":"http://http://www.aferica.site/post/890a9b8e.html","excerpt":"","text":"Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面。Flutter可以与现有的代码一起工作,如阿里闲鱼。在全世界,Flutter正在被越来越多的开发者和组织使用,并且Flutter是完全免费、开源的。 基本介绍-Flutter优势快速开发–热重载Flutter的热重载可帮助您快速地进行测试、构建UI、添加功能并更快地修复错误。在iOS和Android模拟器或真机上可以在亚秒内重载,并且不会丢失状态。 富有表现力,漂亮的用户界面使用Flutter内置美丽的Material Design和Cupertino(iOS风格)widget、丰富的motion API、平滑而自然的滑动效果和平台感知,为您的用户带来全新体验。 原生性能Flutter包含了许多核心的widget,如滚动、导航、图标和字体等,这些都可以在iOS和Android上达到原生应用一样的性能。 对比ReactNative对比ReactNative,Flutter有更好的性能。详细对比参见下面文章: 流言终结者- Flutter和RN谁才是更好的跨端开发方案? Flutter vs React Native 环境配置具体环境配置可以查看官网教程或是中文网教程,以及百度搜索,有很多教程。本文主要介绍Mac配置IOS环境时安装CocoaPods速度过慢的问题。 处理CocoaPods安装过慢1pod setup 这条命令是将Github上的开源库都托管都安装Podspec索引安装到到本地.所以可以直接在GitHub上下载就可以了地址:https://github.com/CocoaPods/Specs如果还是特别慢的话,可以使用这个地址:https://aferica.oss-cn-shenzhen.aliyuncs.com/develop/flutter/Specs-master.zip 2019-07-30更新 使用最新包(600+M),原OSS地址已失效百度云链接: https://pan.baidu.com/s/1y03tWVHQ5AFELM4crcf_Gw 提取码: i31a速度:100kb+,至于更高就要各凭本事了,哈哈哈 如果没有会员,推荐使用http://pandownload.com/,还是很好用的,不过没有MAC版本,只能使用在线版速度:腾讯微云:https://share.weiyun.com/5rIISvd速度:100kb左右 下载后解压,更改文件夹名为master,复制移动到~/.cocoapods/repos即可例如:","categories":[{"name":"Flutter","slug":"Flutter","permalink":"http://http://www.aferica.site/categories/Flutter/"}],"tags":[{"name":"Flutter","slug":"Flutter","permalink":"http://http://www.aferica.site/tags/Flutter/"},{"name":"移动开发","slug":"移动开发","permalink":"http://http://www.aferica.site/tags/移动开发/"},{"name":"CocoaPods","slug":"CocoaPods","permalink":"http://http://www.aferica.site/tags/CocoaPods/"}]},{"title":"wepy小程序引入ColorUI","slug":"wepy小程序引入ColorUI","date":"2019-05-09T06:41:57.000Z","updated":"2019-05-31T08:54:29.927Z","comments":true,"path":"post/60c89aa3.html","link":"","permalink":"http://http://www.aferica.site/post/60c89aa3.html","excerpt":"","text":"好些天没有写博客了,经常感觉自己是一个虎头蛇尾的人,刚接触或者兴致来的时候干劲十足,但是坚持不了多久。搭建这个博客系统就是为了能够给自己一些压力,坚持才是胜利。这次五一算是很长的一个假期,四天里,我感觉自己过得真的是又颓废又尽兴,每天晚上玩到凌晨四五点,下午三四点才起床,然后又开始玩到凌晨四五点,真的是醉生梦死,太恐怖了! 前言随着腾讯的大力推广和用户的熟悉,小程序已经应用在很多场景里面,自然而然,也随之衍生出很多开发框架和组件库。这次我写的是使用wepy作为开发框架和使用ColorUI来开发小程序。 开发框架–wepywepy是由腾讯官方出品的,让小程序支持组件化开发的框架。从Github的Star数来说,还是可以说得上是一个最受欢迎的小程序框架。官方文档地址WePY | 小程序组件化开发框架具体怎么使用我就不说了,毕竟文档说的也比较清楚了,我主要说的是我为什么使用wepy,即他的优势: 支持组件化开发(似乎除了原生,其他开发框架都支持) 支持 slot 组件内容分发插槽 支持 Promise,解决回调烦恼 提供的全局拦截器对原生API的请求进行拦截(这一点很赞) UI组件–ColorUI官方文档地址鲜亮的高饱和色彩,专注视觉的小程序组件库ColorUI是一个css组件库,即所有组件都是通过css实现的,这一点很大佬。而且配色丰富,鲜亮,非常好看。另外,ColorUI提供了一些很棒的,让人眼前一亮的组件或者案例,很有参考、学习的价值。 结合使用由于ColorUI官方示例只有使用UniApp开发和原生开发的案例,所以我尝试了在wepy中使用。同时我也在issues中回答了这个问题,也可以移步这里wepy中怎么引入呢 引入样式文件引入样式文件和文档介绍没有差别,只需要在app.wpy文件中引入即可123456<style lang=\"less\">@import \"./colorui/main.wxss\";@import \"./colorui/icon.wxss\";... //自定义样式</style> 使用自定义导航栏不得不说,ColorUI的自定义导航栏真的让人眼前一亮 修改配置文件app.wpy1234567891011121314151617181920212223242526272829303132333435363738config = { pages: [ 'pages/index' ], window: { backgroundTextStyle: 'light', navigationBarBackgroundColor: '#fff', navigationBarTitleText: 'WeChat', navigationBarTextStyle: 'white', navigationStyle: 'custom' } } // 添加三个全局变量 globalData = { userInfo: null, StatusBar: '', Custom: '', CustomBar: {} } constructor () { super() this.use('requestfix') } onLaunch() { this.testAsync() // 获取设备信息赋值给全局变量 wx.getSystemInfo({ success: e => { this.globalData.StatusBar = e.statusBarHeight let custom = wx.getMenuButtonBoundingClientRect() this.globalData.Custom = custom this.globalData.CustomBar = custom.bottom + custom.top - e.statusBarHeight } }) } 重写(或者说是复制,因为原生代码几乎不需要改动,复制合并即可)cu-custom组件,因为原生组件中app.globalData获取不到数据 cu-custom.wpy1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768<style lang=\"less\"></style><template> <view class=\"cu-custom\" style=\"height: {{CustomBar}}px\"> <view class=\"cu-bar fixed {{bgImage!=''?'none-bg text-white bg-img':''}} {{bgColor}}\" style=\"height:{{CustomBar}}px;padding-top:{{StatusBar}}px;{{bgImage?'background-image:url(' + bgImage+')':''}}\"> <view class=\"action\" bindtap=\"BackPage\" wx:if=\"{{isBack}}\"> <text class=\"cuIcon-back\"></text> <slot name=\"backText\"></slot> </view> <view class=\"action border-custom\" wx:if=\"{{isCustom}}\" style=\"width:{{Custom.width}}px;height:{{Custom.height}}px;margin-left:calc(750rpx - {{Custom.right}}px)\"> <text class=\"cuIcon-back\" bindtap=\"BackPage\"></text> <text class=\"cuIcon-homefill\" bindtap=\"toHome\"></text> </view> <view class=\"content\" style=\"top:{{StatusBar}}px\"> <slot name=\"content\"></slot> </view> <slot name=\"right\"></slot> </view> </view></template><script> import wepy from 'wepy' export default class CuCustom extends wepy.component { props = { bgColor: { type: String, default: '' }, isCustom: { type: [Boolean, String], default: false }, isBack: { type: [Boolean, String], default: false }, bgImage: { type: String, default: '' } } // 获取导航栏样式信息 data = { StatusBar: wepy.$instance.globalData.StatusBar, CustomBar: wepy.$instance.globalData.CustomBar, Custom: wepy.$instance.globalData.Custom } methods = { BackPage () { wepy.navigateBack({ delta: 1 }) }, toHome () { wepy.reLaunch({ url: '/pages/index' }) } } onLoad () { } }</script> 在需要的页面在引入 pages/index.wpy123456789101112131415161718<template> <view> <CuCustom bgColor=\"bg-gradual-blue\"> <view slot=\"content\">导航栏</view> </CuCustom> ... // 页面其他内容 </view></template><script> import CuCustom from '../components/cu-custom' export default class Index extends wepy.page { components = { CuCustom } }</script> 存在问题每次使用都需要在页面中引入,不怎么方便","categories":[{"name":"前端","slug":"前端","permalink":"http://http://www.aferica.site/categories/前端/"},{"name":"小程序","slug":"前端/小程序","permalink":"http://http://www.aferica.site/categories/前端/小程序/"},{"name":"wepy","slug":"前端/小程序/wepy","permalink":"http://http://www.aferica.site/categories/前端/小程序/wepy/"}],"tags":[{"name":"wepy","slug":"wepy","permalink":"http://http://www.aferica.site/tags/wepy/"},{"name":"小程序","slug":"小程序","permalink":"http://http://www.aferica.site/tags/小程序/"},{"name":"ColorUI","slug":"ColorUI","permalink":"http://http://www.aferica.site/tags/ColorUI/"}]},{"title":"Vue-cli 3.0使用CDN引入依赖包和按需引入","slug":"Vue使用CDN引入依赖包","date":"2019-04-29T07:00:09.000Z","updated":"2019-05-31T08:54:29.925Z","comments":true,"path":"post/5eb2f156.html","link":"","permalink":"http://http://www.aferica.site/post/5eb2f156.html","excerpt":"","text":"在Vue开发中过程中,我们会引入许多的依赖包,例如:路由管理vue-router、状态管理vuex和以及一些UI组件库,如Element、iView等,甚至需要添加报表。在开发时我们不会感觉到太大问题,但是当要部署的时候,build结果却提示文件过大如下图(这是一个使用Vue-cli 3.0新建的项目,没有添加任何业务代码,只是引入了Element组件):可想而知,如果在引入其他组件,打包文件就会越来越大,严重影响首页加载速度 以下操作都是基于Vue-cli 3.0项目 下面,我会一步步优化打包体积: 一、按需加载Element官方提供了安秀加载示例,下面我们按照官方教程实现一遍,查看效果 安装babel-plugin-component依赖包(使用Vue UI创建项目可忽略)123npm install babel-plugin-component -D// oryarn add babel-plugin-component --dev 安装vue-cli-plugin-element依赖包(使用Vue UI创建项目可忽略)123npm install vue-cli-plugin-element -D// oryarn add vue-cli-plugin-element --dev 覆盖babel.config.js文件(使用Vue UI创建项目可忽略)1234567891011121314module.exports = { \"presets\": [ \"@vue/app\" ], \"plugins\": [ [ \"component\", { \"libraryName\": \"element-ui\", \"styleLibraryName\": \"theme-chalk\" } ] ]} 引入相关组件 为了方便日后管理维护,我们新建initEle.js来管理引入组件123456789101112131415161718192021222324252627282930313233343536373839404142import { Row, Col, Card, Button, Input, Loading, MessageBox, Message, Notification, Popover, Menu, Submenu, MenuItem, MenuItemGroup, Header, Main} from 'element-ui'const initEle = Vue => { Vue.prototype.$loading = Loading.service Vue.prototype.$msgbox = MessageBox Vue.prototype.$alert = MessageBox.alert Vue.prototype.$confirm = MessageBox.confirm Vue.prototype.$prompt = MessageBox.prompt Vue.prototype.$notify = Notification Vue.prototype.$message = Message Vue.use(Row) Vue.use(Col) Vue.use(Card) Vue.use(Button) Vue.use(Input) Vue.use(Popover) Vue.use(Menu) Vue.use(Submenu) Vue.use(MenuItem) Vue.use(MenuItemGroup) Vue.use(Header) Vue.use(Main)}export default initEle 结果打包后发现成效比较显著 问题 按需加载是通过不引入使用的组件来减少提交的,这是就会有一个问题:如果是Element的重度用户,几乎引入了全部组件,那么按需引入的效果就不明显了 即便不是重度用户,如果网站未使用Gzipped的话也显得较大 使用CDN引入依赖包在public/index.html文件中引入cdn123456789101112131415161718<head> <!-- 引入样式 --> <link href=\"https://cdn.bootcss.com/element-ui/2.7.2/theme-chalk/index.css\" rel=\"stylesheet\"></head><body> <noscript> <strong>We're sorry but vue-template doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> </noscript> <div id=\"app\"></div> <!-- 注意:vue引入开发模式不能使用压缩后的js文件, 即 **.min.js格式, 否则会导致调试工具无法使用 --> <script src=\"https://cdn.bootcss.com/vue/2.6.10/vue.js\"></script> <script src=\"//cdn.bootcss.com/vue-router/3.0.2/vue-router.min.js\"></script> <script src=\"//cdn.bootcss.com/vuex/3.1.0/vuex.min.js\"></script> <script src=\"//cdn.bootcss.com/axios/0.18.0/axios.min.js\"></script> <script src=\"//cdn.bootcss.com/element-ui/2.7.2/index.js\"></script> <!-- built files will be auto injected --></body>... 修改vue.config.js12345678910111213module.exports = { // 添加cdn引用包 configureWebpack: { externals: { 'vue': 'Vue', 'vuex': 'Vuex', 'vue-router': 'VueRouter', 'axios':'axios', 'element-ui': 'ELEMENT' } }, // ...} 覆盖babel.config.js文件12345module.exports = { \"presets\": [ \"@vue/app\" ]} 结果打包后发现成效显著 优点 无需担心引入过多组件依旧导致包体积的问题 使用公共可靠地cdn服务可以加速网站加载 开发环境亦可以使用,配置完成后永绝后患 几乎所有依赖包都可以通过此方式实现 缺点 需要确保cdn服务的稳定和安全 使用cdn引入时,cdn引入的名称有时不一致且不明显,导致引入不成功 开发环境使用cdn通过上述配置,在开发环境也可以使用cdn,不过要注意: 如果需要使用vue devtools来调试,在引入vue的cdn是不能引入*.min.js压缩后的js,否则会导致无法使用调试","categories":[{"name":"前端","slug":"前端","permalink":"http://http://www.aferica.site/categories/前端/"},{"name":"Vue","slug":"前端/Vue","permalink":"http://http://www.aferica.site/categories/前端/Vue/"}],"tags":[{"name":"Vue","slug":"Vue","permalink":"http://http://www.aferica.site/tags/Vue/"},{"name":"CDN","slug":"CDN","permalink":"http://http://www.aferica.site/tags/CDN/"},{"name":"Element","slug":"Element","permalink":"http://http://www.aferica.site/tags/Element/"},{"name":"Vuex","slug":"Vuex","permalink":"http://http://www.aferica.site/tags/Vuex/"},{"name":"Vue-cli3.0","slug":"Vue-cli3-0","permalink":"http://http://www.aferica.site/tags/Vue-cli3-0/"}]},{"title":"mongoDB中聚合aggregate使用","slug":"mongoDB中聚合aggregate使用","date":"2019-04-29T03:42:16.000Z","updated":"2019-05-31T08:54:29.927Z","comments":true,"path":"post/7cc266af.html","link":"","permalink":"http://http://www.aferica.site/post/7cc266af.html","excerpt":"","text":"Aggregate是MongoDB提供的众多工具中的比较重要的一个,类似于SQL语句中的GROUP BY。聚合工具可以让开发人员直接使用MongoDB原生的命令操作数据库中的数据,并且按照要求进行聚合。 Aggregation管道 管道聚合会将上一个命令输出的数据作为下一个命令的参因此相同条件,不同顺序排列,结果也会不同MongoDB中的管道聚合非常实用,提供高效的数据聚合,并且是MongoDB中数据聚合的首选方法 示例图: 常用操作$project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。示例:12345678db.xxx.aggregate( { $project : { // 默认情况下_id字段是被包含的,如果要想不包含_id话可以通过下面方式: _id: 0, title : 1 , author : 1 , }}); $match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。示例:12345678910db.xxx.aggregate( { $match : { publish_date: { $lte: 'xxxx', $gt: 'xxxx' } } }); $limit:用来限制MongoDB聚合管道返回的文档数。示例:123db.xxx.aggregate( { $limit : 10}); $skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。示例:123db.xxx.aggregate( { $skip : 20}); $unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。 该方法主要使用场景,统计数组类型字段中每一个类型数量,如:标签数据、演员数据示例:123db.xxx.aggregate( { $unwind : '$tags'} // tags是字段名 前必须添加$符); $group:将集合中的文档分组,可用于统计结果。统计某个字段数量:123456db.xxx.aggregate( { $group : { _id: '$title', // titile是字段名 前必须添加$符 count: { $sum :1 } // 用作统计 }}); $sort:将输入文档排序后输出。 对统计结果排序 和普通排序命令相同示例:12345db.xxx.aggregate( { $sort : { count: -1 // 按照`$group`分组字段数量降序排序 }} );","categories":[{"name":"数据库","slug":"数据库","permalink":"http://http://www.aferica.site/categories/数据库/"},{"name":"mongoDB","slug":"数据库/mongoDB","permalink":"http://http://www.aferica.site/categories/数据库/mongoDB/"}],"tags":[{"name":"mongoDB","slug":"mongoDB","permalink":"http://http://www.aferica.site/tags/mongoDB/"},{"name":"mongoose","slug":"mongoose","permalink":"http://http://www.aferica.site/tags/mongoose/"}]},{"title":"搭建自己API服务器(三):部署到服务器","slug":"搭建自己API服务器(三):部署到服务器","date":"2019-04-29T01:44:13.000Z","updated":"2019-05-31T08:54:29.924Z","comments":true,"path":"post/65aa62c3.html","link":"","permalink":"http://http://www.aferica.site/post/65aa62c3.html","excerpt":"","text":"egg是阿里巴巴团队推出的基于Node.js和Koa的为企业级框架和应用详细文档,了解更多 上传代码到服务器可以通过Git、FileZilla等多种方式上传 启动1234npm i // 需要安装依赖才行npm start // 启动生产环境 egg会自动后台管理npm stop // 结束 nginx转发使用http1234567891011server { listen 80; server_name ***.***; location / { proxy_pass http://127.0.0.1:7001/; proxy_connect_timeout 1; proxy_send_timeout 30; proxy_read_timeout 60; }} 使用https12345678910111213141516171819202122server { listen 443; server_name ***.***; // 访问域名 ssl on; ssl_certificate ****.pem; ssl_certificate_key ****.key; // 证书地址 ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #按照这个协议配置 ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; #按照这个套件配置 ssl_prefer_server_ciphers on; client_max_body_size 20m; location / { proxy_pass http://127.0.0.1:7001/; // 端口地址 proxy_connect_timeout 1; proxy_send_timeout 30; proxy_read_timeout 60; }}","categories":[{"name":"后端","slug":"后端","permalink":"http://http://www.aferica.site/categories/后端/"},{"name":"Node","slug":"后端/Node","permalink":"http://http://www.aferica.site/categories/后端/Node/"}],"tags":[{"name":"API","slug":"API","permalink":"http://http://www.aferica.site/tags/API/"},{"name":"服务器","slug":"服务器","permalink":"http://http://www.aferica.site/tags/服务器/"},{"name":"egg","slug":"egg","permalink":"http://http://www.aferica.site/tags/egg/"},{"name":"Node","slug":"Node","permalink":"http://http://www.aferica.site/tags/Node/"}]},{"title":"搭建自己API服务器(二):添加功能模块","slug":"搭建自己API服务器(二):添加功能模块","date":"2019-04-29T01:06:42.000Z","updated":"2019-05-31T08:54:29.927Z","comments":true,"path":"post/23e54749.html","link":"","permalink":"http://http://www.aferica.site/post/23e54749.html","excerpt":"","text":"egg是阿里巴巴团队推出的基于Node.js和Koa的为企业级框架和应用详细文档,了解更多 添加自己的模块(例如添加book模块)开发自己的模块主要需要添加或修改的文件有三个(如果使用mongoose的话则是四个)分别是 添加book相关路由1router.get('/api/book', controller.book.index) 添加app/controller/book.js1234567891011121314151617181920212223242526272829const Controller = require('egg').Controllerclass BookController extends Controller { constructor(ctx) { super(ctx) } // 获取所有类型(分页/模糊) async index() { const { ctx, service } = this // 组装参数 const payload = ctx.query // 调用 Service 进行业务处理 /** * 此处service.book.index意思是调用service文件夹下的book.js中的index方法 * egg无需添加引入语句,会自动引入,但是路径必须正确 * 例如:如果book是在service文件夹下的other文件夹之中 * 引用用具则变为: service.other.book.index */ const res = await service.book.index(payload) // 设置响应内容和响应状态码 ctx.helper.success({ctx, res}) } // 更多}module.exports = BookController 添加app/service/book.js1234567891011121314151617181920212223242526272829303132333435363738394041424344const Service = require('egg').Serviceclass BookService extends Service { // index======================================================================================================> async index(payload) { let limit = 20 let page = 1 if(payload.limit) { limit = parseInt(payload.limit) delete payload.limit } if(payload.page) { page = parseInt(payload.page) delete payload.page } let res = [] let count = 0 let sort = { last_update: -1 } count = await this.ctx.model.book.count(payload).exec() /** * 此处this.ctx.model.book意思是调用model文件夹下的book.js中的Book数据模型 * egg无需添加引入语句,会自动引入,但是路径必须正确 */ res = await this.ctx.model.book.find(payload).skip((page - 1) * limit).limit(limit).sort(sort).exec() // 数据整理,格式化 let data = res.map((e,i) => { const jsonObject = Object.assign({}, e._doc) jsonObject.key = i + 1 + (page - 1) * limit delete jsonObject.page_url delete jsonObject.have_all_info delete jsonObject.create_time return jsonObject }) return { count: count, list: data, limit: limit, page: page } } // 更多}module.exports = BookService 添加app/model/book.js 注意:model文件夹下不能再新建子文件夹,否则会导致model找不到 1234567891011121314151617181920module.exports = app => { const mongoose = app.mongoose const BookSchema = new mongoose.Schema({ title: { type: String, default: '' }, cover: { type: String, default: '' }, type: { type: String, default: '' }, size: { type: String, default: '' }, short_intro: { type: String, default: ''}, uploader: { type: String, default: ''}, good: { type: Number, default: 0 }, bad: { type: Number, default: 0 }, page_url: { type: String, default: ''}, last_update: { type: String, default: '' }, create_time: { type: String, default: '' } }, {collection: 'book'}) /** * 注意:此处{collection: 'book'}为数据库表名称,如果不自定义表名,会默认为model名称复数形式:books */ return mongoose.model('Book', BookSchema)}","categories":[{"name":"后端","slug":"后端","permalink":"http://http://www.aferica.site/categories/后端/"},{"name":"Node","slug":"后端/Node","permalink":"http://http://www.aferica.site/categories/后端/Node/"}],"tags":[{"name":"API","slug":"API","permalink":"http://http://www.aferica.site/tags/API/"},{"name":"服务器","slug":"服务器","permalink":"http://http://www.aferica.site/tags/服务器/"},{"name":"egg","slug":"egg","permalink":"http://http://www.aferica.site/tags/egg/"},{"name":"Node","slug":"Node","permalink":"http://http://www.aferica.site/tags/Node/"}]},{"title":"搭建自己API服务器(一):使用egg快速搭建","slug":"搭建自己API服务器(一):egg入门","date":"2019-04-28T06:52:03.000Z","updated":"2019-05-31T08:54:29.922Z","comments":true,"path":"post/ec07fb1c.html","link":"","permalink":"http://http://www.aferica.site/post/ec07fb1c.html","excerpt":"","text":"egg是阿里巴巴团队推出的基于Node.js和Koa的为企业级框架和应用详细文档,了解更多 环境要求 操作系统:支持 macOS,Linux,Windows 运行环境:Node建议选择 LTS 版本,最低要求 8.x。 egg项目结构该目录说明来源中egg文档,具体可查目录结构12345678910111213141516171819202122232425262728293031323334353637egg-project├── package.json├── app.js (可选)├── agent.js (可选)├── app| ├── router.js│ ├── controller│ | └── home.js│ ├── service (可选)│ | └── user.js│ ├── middleware (可选)│ | └── response_time.js│ ├── schedule (可选)│ | └── my_task.js│ ├── public (可选)│ | └── reset.css│ ├── view (可选)│ | └── home.tpl│ └── extend (可选)│ ├── helper.js (可选)│ ├── request.js (可选)│ ├── response.js (可选)│ ├── context.js (可选)│ ├── application.js (可选)│ └── agent.js (可选)├── config| ├── plugin.js| ├── config.default.js│ ├── config.prod.js| ├── config.test.js (可选)| ├── config.local.js (可选)| └── config.unittest.js (可选)└── test ├── middleware | └── response_time.test.js └── controller └── home.test.js 如上,由框架约定的目录: app/router.js 用于配置 URL 路由规则,具体参见 Router。 app/controller/** 用于解析用户的输入,处理后返回相应的结果,具体参见 Controller。 app/service/** 用于编写业务逻辑层,可选,建议使用,具体参见 Service。 app/middleware/** 用于编写中间件,可选,具体参见 Middleware。 app/public/** 用于放置静态资源,可选,具体参见内置插件 egg-static。 app/extend/** 用于框架的扩展,可选,具体参见框架扩展。 config/config.{env}.js 用于编写配置文件,具体参见配置。 config/plugin.js 用于配置需要加载的插件,具体参见插件。 test/** 用于单元测试,具体参见单元测试。 app.js 和 agent.js 用于自定义启动时的初始化工作,可选,具体参见启动自定义。由内置插件约定的目录: app/public/** 用于放置静态资源,可选,具体参见内置插件 egg-static。 app/schedule/** 用于定时任务,可选,具体参见定时任务。 若需自定义自己的目录规范,参见 Loader API app/view/** 用于放置模板文件,可选,由模板插件约定,具体参见模板渲染。 app/model/** 用于放置领域模型,可选,由领域类相关插件约定,如 egg-sequelize。 快速搭建API服务框架方法一:使用我自己搭建的demo 该demo是使用egg + mongodb + jsonwebtoken实现的一个简单的RESTful API服务器模板具体说明查看项目介绍 12345git clone https://github.com/aferica/egg-api-severcd egg-api-severyarnnpm run devopen http://localhost:7001/ 方法二:使用官方推荐的egg-RESTfulAPI 框架选择:基于 Egg.js 2.0数据模型:基于 Mongoose 存储授权验证:基于JWT内置功能:文件处理,用户系统,统一错误处理及接口返回标准,全方位CRUD,分页,模糊查询的等数据操作Demo最佳实践:接口设计适配 Ant Design Pro 或 微信小程序开发等。(内置分页及ant接口返回标准) 1234cd app & mkdir public & cd public & mkdir uploadsnpm inpm run devopen http://localhost:7001/ 配置管理egg框架提供了强大且可扩展的配置功能,可以自动合并应用、插件、框架的配置,按顺序覆盖,且可以根据环境维护不同的配置。合并后的配置可直接从 app.config 获取。 多环境配置 多个环境配置文件,适用于多种环境,方便管理维护 1234config|- config.default.js // 默认配置文件|- config.prod.js // 正式环境配置文件|- config.test.js // 测试配置文件 配置示例12345678910111213141516// egg-mongoose配置config.mongoose = { url: 'mongodb://127.0.0.1:27017/egg_x', options: { useMongoClient: true, autoReconnect: true, reconnectTries: Number.MAX_VALUE, bufferMaxEntries: 0, },}// jwt配置config.jwt = { secret: 'Great4-M', enable: true, // default is false match: '/jwt', // optional}","categories":[{"name":"后端","slug":"后端","permalink":"http://http://www.aferica.site/categories/后端/"},{"name":"Node","slug":"后端/Node","permalink":"http://http://www.aferica.site/categories/后端/Node/"}],"tags":[{"name":"API","slug":"API","permalink":"http://http://www.aferica.site/tags/API/"},{"name":"服务器","slug":"服务器","permalink":"http://http://www.aferica.site/tags/服务器/"},{"name":"egg","slug":"egg","permalink":"http://http://www.aferica.site/tags/egg/"},{"name":"Node","slug":"Node","permalink":"http://http://www.aferica.site/tags/Node/"}]},{"title":"Chrome常用插件推荐","slug":"Chrome常用插件推荐","date":"2019-04-28T06:08:22.000Z","updated":"2019-05-31T08:54:29.924Z","comments":true,"path":"post/7e479bd5.html","link":"","permalink":"http://http://www.aferica.site/post/7e479bd5.html","excerpt":"","text":"Chrome浏览器是目前使用人数最多的浏览器,由于其优秀的功能,丰富的插件,对开发者友好的特点,几乎是程序开发必备。下面推荐几个个人觉得好用的,甚至是必须的插件。 Restlet Client(API测试工具)提到API测试工具,很多人第一时间想到的应该都是Postman这款工具,但是个人感觉太大了一些,于是我找到了这款工具:从上图可以看出,该工具还是比较受欢迎的 优点 轻量级,就如同网页一般,随用随开,可离线 界面美观,使用方便 免费款极客满足日常所有需要 无广告 功能齐全 二维码生成器 (Quick QR)Chrome上好评率最高的二维码生成器:可以方便地把当前页面转化成二维码,也可以把网页上任何文本或链接,甚至是您输入的任意内容都转化成二维码 功能 快速把任意当前页面生成二维码 把页面上的任何链接生成二维码 您可以输入任何内容生成二维码 无需联网、无需授权(安全可靠,童叟无欺) Proxy SwitchyOmega(科学上网代理)作为一名辛劳的程序员,怎么可以不回科学上网? 网盘万能钥匙(成功率极高)看到自己想要的资源,但是不知道密码?每次都要复制粘贴,麻烦?这个插件绝对可以解决你的烦恼。 网上商店似乎搜不到了 略尴尬 但是真的好用 Vue DevtoolsVue开发者必备","categories":[{"name":"工具","slug":"工具","permalink":"http://http://www.aferica.site/categories/工具/"}],"tags":[{"name":"Chrome","slug":"Chrome","permalink":"http://http://www.aferica.site/tags/Chrome/"},{"name":"工具","slug":"工具","permalink":"http://http://www.aferica.site/tags/工具/"}]},{"title":"追书神器API整理","slug":"追书神器API整理","date":"2019-04-26T06:29:38.000Z","updated":"2019-05-31T08:54:29.922Z","comments":true,"path":"post/5cb31f79.html","link":"","permalink":"http://http://www.aferica.site/post/5cb31f79.html","excerpt":"","text":"分类带书籍数量的父分类url: http://api.zhuishushenqi.com/ranking/gender response: 123456789101112131415161718192021222324{ \"male\": [ { \"name\": \"玄幻\", \"bookCount\": 429247 }, { \"name\": \"奇幻\", \"bookCount\": 41711 } ], \"female\": [ { \"name\": \"古代言情\", \"bookCount\": 338664 }, { \"name\": \"现代言情\", \"bookCount\": 395887 } ... ] \"press\": []} 带子分类的父分类url: http://api.zhuishushenqi.com/cats/lv2 response: 1234567891011121314151617181920212223{ \"male\": [ { \"major\": \"玄幻\", \"mins\": [ \"东方玄幻\", \"异界大陆\", \"异界争霸\", \"远古神话\" ] }, { \"major\": \"奇幻\", \"mins\": [ \"西方奇幻\", \"领主贵族\", \"亡灵异族\", \"魔法校园\" ] } ] ...} 获取分类书籍(categoryInfo)request: 123456789query:{ gender: 'male' // 性别 type: 'reputation' // 按照不同的类型获取分类下的书籍(hot, new, reputation, over) major: '玄幻' // 父分类 minor: '东方玄幻' // 子分类 start: 0 // 起始位置 limit: 20 //每页数量} response: 123456789101112{ _id: 书籍id title: 书籍名 author: 作者 shortIntro: 简介 cover: 封面 site: 书源 latelyFollower: 追书人数 retentionRatio: 好评率(%) lastChater: 最新章节 tag: 标签} 书籍书籍详情url: http://api.zhuishushenqi.com/book/:id request: 123url params: { id: BookId} response: 12345678910111213141516171819202122232425262728293031{ \"_id\": \"5106099abb1c67cf28000016\", //书籍id \"author\": \"禹枫\", //作者 \"cover\": \"/agent/http://images.zhulang.com/book_cover/image/18/98/189843.jpg\", // 封面 \"creater\": \"iPhone 4\", \"longIntro\": \"...\", //长介绍 \"title\": \"异世灵武天下\", //书名 \"cat\": \"东方玄幻\", \"majorCate\": \"玄幻\", //主分类 \"minorCate\": \"东方玄幻\", //子分类 \"_le\": false, \"allowMonthly\": true, \"allowVoucher\": true, \"allowBeanVoucher\": true, \"hasCp\": true, \"postCount\": 3183, \"latelyFollower\": 43192, //追书人数 \"followerCount\": 5164, \"wordCount\": 11241234, //总字数 \"serializeWordCount\": 129762, //平均 \"retentionRatio\": \"66.16\", //好评率 \"updated\": \"2017-01-19T05:58:53.799Z\", //更新于 \"isSerial\": false, //连载中 \"chaptersCount\": 3577, //总章数 \"lastChapter\": \"后续第五章:大结局终章\", //最新章节 \"gender\": [ \"male\" ], \"tags\": [], \"donate\": false} 书籍章节这部分相对比较复杂 步骤如下: 书籍id -> 获取所有书源 -> 书源id -> 获取章节目录 -> 章节link -> 章节内容 书籍id 5779b38d3b433dd647d95da2 获取所有书源 [http://api.zhuishushenqi.com/atoc/?view=summary&book=5779b38d3b433dd647d95da2] response: 123456789101112131415[ { \"_id\": \"5881e82e3e3357fa266f6a3e\", \"source\": \"zhuishuvip\", \"name\": \"优质书源\", \"link\": \"http://vip.zhuishushenqi.com/toc/5881e82e3e3357fa266f6a3e\", \"lastChapter\": \"第1016章 扑朔迷离(大结局)\", \"isCharge\": false, \"chaptersCount\": 1029, \"updated\": \"2017-12-26T05:16:04.709Z\", \"starting\": true, \"host\": \"vip.zhuishushenqi.com\" }, ...] 书源id 5881e82e3e3357fa266f6a3e 获取章节目录 [http://api.zhuishushenqi.com/btoc/5881e82e3e3357fa266f6a3e?view=chapters] response: 123456789101112131415161718{ \"_id\": \"5881e82e3e3357fa266f6a3e\", \"name\": \"优质书源\", \"link\": \"http://vip.zhuishushenqi.com/toc/5881e82e3e3357fa266f6a3e\", \"book\": \"5779b38d3b433dd647d95da2\", \"chapters\": [ { \"title\": \"第一章 状元再世\", // 章节名 \"link\": \"http://vip.zhuishushenqi.com/chapter/5881e82e4e307ea47f89deeb?cv=1484908590347\", //章节地址 \"id\": \"5881e82e4e307ea47f89deeb\", //章节id \"currency\": 10, //价格 \"unreadble\": false, \"isVip\": false // 是否是vip章节 } ], \"updated\": \"2017-03-31T14:44:51.413Z\", //更新于 \"host\": \"vip.zhuishushenqi.com\" // 书源} 章节link http://vip.zhuishushenqi.com/chapter/5881e82e4e307ea47f89deeb?cv=1484908590347 章节内容 如下: 章节内容url: http://chapter2.zhuishushenqi.com/chapter/:chapterLink request:123url params: { chapterLink: 'http://vip.zhuishushenqi.com/chapter/5881e82e4e307ea47f89df43' // 章节地址} response: 1234567891011{ \"ok\": true, \"chapter\": { \"title\": \"第八十九章 杂阿神功(二)\", // 章节名 \"body\": \"\\n\\r\\n\\r\\n\\r请安装最新版追书 以便使用优质资源\", \"isVip\": true, \"cpContent\": \"..\", //章节内容 \"currency\": 10, \"id\": \"5881e82e4e307ea47f89df43\" }} 作者的书籍url: http://api.zhuishushenqi.com/book/accurate-search?author=忘语 request: 123url params: { author: 作者名} response: 12345678910111213141516171819202122{ \"books\": [ { \"_id\": \"567d2cb9ee0e56bc713cb2c0\", \"title\": \"玄界之门\", \"author\": \"忘语\", \"shortIntro\": \"...\", \"cover\": \"/cover/148369972991098\", \"cat\": \"仙侠\", \"site\": \"zhuishuvip\", \"majorCate\": \"仙侠\", \"minorCate\": \"幻想修仙\", \"banned\": 0, \"latelyFollower\": 35504, \"followerCount\": 0, \"retentionRatio\": 65.18, \"lastChapter\": \"第919章 前线告急\" }, ... ], \"ok\": true} 排名排名分类url: http://api.zhuishushenqi.com/ranking/gender response: 1234567891011{ \"female\": [ { \"_id\": \"54d43437d47d13ff21cad58b\", //周榜 \"title\": \"追书最热榜 Top100\", \"cover\": \"/ranking-cover/142319314350435\", \"collapse\": false, \"monthRank\": \"564d853484665f97662d0810\", //月榜 \"totalRank\": \"564d85b6dd2bd1ec660ea8e2\" // 总榜 } } 排名详情url: http://api.zhuishushenqi.com/ranking/:id request: 123url params: { id: 排名id //周榜等} response: 12345678910111213141516171819202122232425262728293031323334{ \"ranking\": { \"_id\": \"54d42d92321052167dfb75e3\", \"updated\": \"2017-03-31T21:20:09.135Z\", \"title\": \"追书最热榜 Top100\", \"tag\": \"zhuishuLatelyFollowerMale\", \"cover\": \"/ranking-cover/142319144267827\", \"icon\": \"/cover/148945782817557\", \"__v\": 790, \"monthRank\": \"564d820bc319238a644fb408\", \"totalRank\": \"564d8494fe996c25652644d2\", \"created\": \"2017-04-01T03:20:20.988Z\", \"isSub\": false, \"collapse\": false, \"new\": true, \"gender\": \"male\", \"priority\": 250, \"books\": [ { \"_id\": \"51d11e782de6405c45000068\", \"author\": \"天蚕土豆\", \"cover\": \"/agent/http://image.cmfu.com/books/2750457/2750457.jpg\", \"shortIntro\": \"大千世界,位面交汇,万族林立,群雄荟萃,一位位来自下位面的天之至尊,在这无尽世界,演绎着令人向往的传奇,追求着那主宰之路。 无尽火域,炎帝执掌,万火焚苍穹。 武...\", \"title\": \"大主宰\", \"site\": \"zhuishuvip\", \"cat\": \"玄幻\", \"banned\": 0, \"latelyFollower\": 359456, \"retentionRatio\": \"45.31\" } ] ... ok: true } 书评讨论url: http://api.zhuishushenqi.com/post/by-book?&start=21&limit=20 request:1234567query strings: { book: {bookId}, sort: (updated|created|comment-count) // 排序方式 type: (normal,vote) // 未知 start, limit} response: 12345678910111213141516171819202122232425{ "posts": [{ "_id": "59b25a1ca17d25ad324e208d", "author": { "_id": "54ef4d94704d6be45528af89", "avatar": "/avatar/34/bb/34bbc2992b34e6a042a83be1f6f3b735", //http://statics.zhuishushenqi.com "nickname": "追书家的小萝莉", "activityAvatar": "/activities/20170120/1.jpg", "type": "official", "lv": 9, "gender": "female" }, "type": "vote", "likeCount": 371, "block": "ramble", "haveImage": true, "state": "normal", "updated": "2017-09-16T05:38:16.092Z", "created": "2017-09-08T08:51:40.345Z", "commentCount": 5309, "voteCount": 3980, "title": "【真够刺激】答题拿红包!邀请好友满30元就能提现!★攻略真的不先看下么!" }], "ok": true} 短评url: http://api.zhuishushenqi.com/post/short-review/by-book request:123456query strings: { book: {bookId}, sortType: (lastUpdated|newest|mostlike) //排序方式 start, limit} response:12345678910111213141516171819202122232425262728293031{ "docs": [ { "_id": "596affc7fe0ad34f1b8317e3", "rating": 3, "type": "short_review", "author": { "_id": "596ac9b85d0fe1b460155952", "avatar": "/avatar/bd/bf/bdbf666388552ebb3166473e3f689dfd", "nickname": "素心", "activityAvatar": "", "type": "normal", "lv": 4, "gender": "female" }, "book": { "_id": "51060c88bb1c67cf28000035", "cover": "/agent/http%3A%2F%2Fimg.1391.com%2Fapi%2Fv1%2Fbookcenter%2Fcover%2F1%2F23766%2F_23766_549079.jpg%2F", "title": "真灵九变" }, "likeCount": 2, "priority": 0.497, "block": "short_review", "state": "normal", "updated": "2017-08-06T09:58:26.733Z", "created": "2017-07-16T05:55:19.277Z", "content": "就是结尾有点烂尾了" } ], "ok": true} 长评url: http://api.zhuishushenqi.com/post/review/by-book?book=51060c88bb1c67cf28000035&sort=updated&start=0&limit=20 request:123456query strings: { book: {bookId}, sort: (updated|created|comment-count), start, limit} response:1234567891011121314151617181920212223242526272829{ "total": 35, "reviews": [{ "_id": "584201194fe8537c0f7fdf32", "rating": 1, "author": { "_id": "580cc42178afb3190f41f5ae", "avatar": "/avatar/b3/70/b370b0054ae878829bfae3fe8ceacf3e", "nickname": "……", "activityAvatar": "/activities/20170120/4.jpg", "type": "normal", "lv": 8, "gender": "male" }, "helpful": { "total": 35, "yes": 117, "no": 82 }, "likeCount": 5, "state": "normal", "updated": "2017-09-13T15:08:48.577Z", "created": "2016-12-02T23:17:45.711Z", "commentCount": 76, "content": "1)一边声明“猪脚资质一般”,一边又在没有“穿越神器”的情况下给猪脚开挂。修炼速度莫名其妙就比其他人快,这也是“资质一般”?能自圆其说不?\\n\\n2)明明是凡人流里那种勾心斗角杀人夺宝的世界,猪脚的朋友未免太多了吧?还各个都为猪脚着想,围着猪脚转?凡人流啊!那是神马鸡毛世界,那是人人都可能在你身后打闷棍的世界。想玩哥们弟兄义气江湖的,请出门左手见《飘渺之旅》下车。\\n\\n3)“俏皮、傲娇”的女主!我拉个擦,这个基本是所有YY书的鹤顶红了,本以为绝迹几千年,没想到还能见!\\n\\n4)师姐,不是1个,是10个!我进错门了吗?这是许仙传吗?真是许仙传就好了!这分明是睡裤外穿、浓妆艳抹的乡下小保姆嘛!\\n\\n5)美少妇师傅!你到底想写啥?玩后宫,人妻的请出门右转进晋江。\\n\\n6)N个陷害猪脚,差点让猪脚死球的同门,猪脚被坑了一次又一次,从来不报复,从来不想解决,于是被人从头坑到尾。请问,你是白求恩还是科利华?还是传说中的圣雄甘地?\\n\\n7)猪脚开挂升级也就罢了,猪脚的朋友们也是哥哥开挂。一开始书中声称“升溶血修士如何如何难,升锻蛋修士更是千中无一”,好,猪脚开挂,奇遇不断,十几年升到锻蛋!贫道以为这已经是牛逼透顶的了,结果再看,猪脚的朋友们也一个个都锻蛋了!这尼玛也是“如何如何难”?“千中无一”??拜托你学凡人流,看过凡人没有???更恶心的是,就连猪脚随便找得几个土匪小弟,也一个个吃猪尿泡一样升锻蛋了。我。。。。叉。。。。", "title": "个人观点,看书前最好看看!" }], "ok": true} 书单列表url: http://api.zhuishushenqi.com/book-list request: 12345678910111213query string: { sort: (collectorCount|created), duration: (last-seven-days|all), gender: (male|female), tag: (有点多), start}说明:本周最热的query是: sort=collectorCount&duration=last-seven-days&start=0最新发布是: sort=created&duration=all最多收藏是: sort=collectorCount&duration=all response:12345678910111213141516{ "total": 241518, "bookLists": [ { "_id": "57331505025ffaa06cb28852", "title": "★星光书局 ★(04-20更", "author": "人闲", "desc": "☆准星(不好看),★一星,★★二星,★★★三星,★★★★,★★★★★五星 (持续更新中……)……………本期歌单:周慧敏《自作多情》、赵雷《已是两条路上的人》、张韶涵《寓言》、张惠妹《我最亲爱的》、张惠妹《哭砂》、张惠妹《剪爱》、张碧晨《渡红尘》、Amy Winehouse《You know I'm no good》、邓紫棋《偶尔》、邓紫棋《喜欢你》、叶倩文《曾经心疼》、叶倩文《祝福》", "gender": "male", "collectorCount": 96298, "cover": "/agent/http%3A%2F%2Fimg.1391.com%2Fapi%2Fv1%2Fbookcenter%2Fcover%2F1%2F41678%2F_41678_412098.jpg%2F", "bookCount": 464 } ], "ok": true} 详情url: http://api.zhuishushenqi.com/book-list/:bookId request: 123url params: { bookId: {bookId}} response:1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950{ "bookList": { "_id": "57331505025ffaa06cb28852", "updated": "2017-05-25T03:18:20.437Z", "title": "★星光书局 ★(04-20更", "author": { "_id": "568dcb55f08722bf2bdeeb38", "avatar": "/avatar/41/32/41327b6d253592bb644fa4dd4c5c9b03", "nickname": "人闲", "type": "normal", "lv": 9 }, "desc": "☆准星(不好看),★一星,★★二星,★★★三星,★★★★,★★★★★五星 (持续更新中……)……………本期歌单:周慧敏《自作多情》、赵雷《已是两条路上的人》、张韶涵《寓言》、张惠妹《我最亲爱的》、张惠妹《哭砂》、张惠妹《剪爱》、张碧晨《渡红尘》、Amy Winehouse《You know I'm no good》、邓紫棋《偶尔》、邓紫棋《喜欢你》、叶倩文《曾经心疼》、叶倩文《祝福》", "gender": "male", "created": "2016-05-11T11:18:29.278Z", "tags": [ "热血", "都市", "现代" ], "stickStopTime": null, "isDraft": false, "isDistillate": false, "collectorCount": 96299, "books": [ { "book": { "cat": "东方玄幻", "_id": "579eaef492253c435235dbea", "title": "斗战狂潮", "author": "骷髅精灵", "longIntro": "双月当空,无限可能的英魂世界孤寂黑暗,神秘古怪的嬉命小丑百城联邦,三大帝国,异族横行,魂兽霸幽这是一个英雄辈出的年代,人类卧薪尝胆重掌地球主权,孕育着进军高纬度的野望!重点是……二年级的废柴学长王同学,如何使用嬉命轮盘,撬动整个世界,学妹们,请注意,学长来了!!!斗战一群:21222419(两千人战力群)骷髅的微信公共号:kuloujingling00新浪微博:骷髅精灵", "cover": "/agent/http%3A%2F%2Fimg.1391.com%2Fapi%2Fv1%2Fbookcenter%2Fcover%2F1%2F1286280%2F_1286280_696459.jpg%2F", "site": "zhuishuvip", "majorCate": "玄幻", "minorCate": "东方玄幻", "banned": 0, "latelyFollower": 26038, "wordCount": 1962241, "retentionRatio": 60.36 }, "comment": "★★二星…………" } ], "shareLink": "http://share.zhuishushenqi.com/booklist/57331505025ffaa06cb28852", "id": "57331505025ffaa06cb28852", "total": 464 }, "ok": true} 获取最新章节url: http://api.zhuishushenqi.com/book request: 1234url params: { view: 'updated', id: 'id=5afa99a6e1a9635af90fc802,55eef8b27445ad27755670b9' // bookId 多个使用,隔开} response:1234567891011121314151617181920[ { \"_id\": \"5afa99a6e1a9635af90fc802\", \"author\": \"上山打老虎额\", \"allowMonthly\": false, \"referenceSource\": \"default\", \"updated\": \"2019-02-22T15:33:39.695Z\", \"chaptersCount\": 1135, \"lastChapter\": \"正文卷 第一千零七十三章:圣天子也\" }, { \"_id\": \"55eef8b27445ad27755670b9\", \"author\": \"圣骑士的传说\", \"allowMonthly\": false, \"referenceSource\": \"default\", \"updated\": \"2019-02-22T16:02:40.095Z\", \"chaptersCount\": 2529, \"lastChapter\": \"第2521章 角度就是这么刁钻\" }]","categories":[{"name":"API","slug":"API","permalink":"http://http://www.aferica.site/categories/API/"}],"tags":[{"name":"API","slug":"API","permalink":"http://http://www.aferica.site/tags/API/"},{"name":"追书神器","slug":"追书神器","permalink":"http://http://www.aferica.site/tags/追书神器/"}]}]}