作为过山车狂热粉丝的我,一直都想挑战蹦极和跳伞。但因为并没有合适的契机(主要是没有志同道合的朋友),所以我人生中的二十多年以来,居然从来没有体验过这种有趣的运动。
那天,突然收到老王的微信,:“想不想去跳伞?Bills on me”。还有这等好事,也不是我贪别人请我(吗?),主要是我真爱跳伞这项运动。
时间定在了周四,我们预约的下午2点跳伞,但开车要花两个多小时,加上是第一次跳伞,所以我们最终选择10点出发。1月份的天还是挺冷的,虽然出了太阳,但天气预报说有雨,让我内心还是很慌张的。
到了地方后登记和交钱,就开始坐在那排队。等了十几分钟后,两个教练出来喊我们的名字,我的那个教练一直想念我的中文名字,但是发音一直不对(😂),所以我就让他喊我Evin了。
再简单地与我们沟通了注意事项,以及在空中的手势后,我们坐上了去往起飞机场的车。
其实刚开始我是没有感觉的,直到我看到那个小飞机,我才意识到:“我真的要坐上这个飞机了,我要从2000米的高空中跳下来”。为此我还脑补了刺客信条系列里主角的信仰之跃,以及林克在海拉鲁大陆上从山峰一路滑翔往下的场景。
上了飞机后,能明显感觉到拥挤,我坐在教练怀里,以一种非常奇怪且少儿不宜的姿势,像连体婴儿一样和他固定在一起。随着小破飞机的引擎声响起,直升机开始垂直盘旋向上。随着起飞的机场逐渐越变越小,窗外的云朵也开始出现,缠绕在我们四周。
教练让我们选一个人先跳,我把这个机会让给老王了,因为我想让在空中待久一点。教练的其中一个把舱门拉开了,瞬间整个小机舱都被冷空气灌满,本来那天就挺冷的,这猛的一下应是给我冻的一激灵。老王和他的教练慢慢地起身,踩在飞机的起落架上,他望了我一眼,然后猛的一下跳下去了,再回过神看,我的视野中就只有一个黯淡的小蓝点了。
轮到我了,不夸张地说,我现在回忆这段经历的时候手心都还在冒汗。我先把手搭在了机翼上,然后一股冷到骨髓里的寒气向我袭来,就像是下着雪的冬天里,不知深浅地伸手摸了一把铁栏杆一样。接着我也踩到了起落架上,头从机舱出来的瞬间,我就“失聪”了,除了快速流动的风声外,还是风声。没等我有所反应,教练就开始倒计时3,2,1… 跳入这片广袤无际的蔚蓝之中了
巨大的空气阻力撞击着我,我整个人180度翻转过来,明晃晃的阳光高悬在青空上,我感觉我离它前所未有的近。呼啸的风声从我脸颊两侧刷刷飞过,我整个人又翻转回来,就这样来来回回好几次,教练拍了拍我的手臂,示意我可以张开手臂滑翔了。在玩过王国之泪之后,是不是觉得我描述的很像游戏中的场景?但是真正的跳伞居然真是这样的!(😂)
就这样,我疯狂向下俯冲,大概过了几十秒左右,我整个人受到一股向上的牵引力,但由于在惯性的作用下,我的身体还在高速下降,这突如其来的停顿让我的大腿根被勒的生疼。不过好在那风声已经弱了很多,我鸟瞰地面,突然一股劫后余生的轻松涌现。
我暂时地宣布,跳伞是我最喜欢的极限运动。
越来越多的应用使用非对称加密来传输数据,例如我经常会用到的OpenSSH。它提供一组私钥和公钥。公钥就像是一把锁,用来加密数据,不能用来解密数据,可以随便交给他人。私钥就像钥匙,可以解密数据,但无法加密数据。
但在使用远程主机的某些程序时,我却经常需要本地机器的密钥来授权。最简单的做法就是将密钥手动粘贴过去,但这种做法却很危险。首先,远程主机暴露在公网中,会遭受大量攻击,而本地主机几乎不会被攻击。再者,粘贴行为需要进行网络传输,那么它就并不能保证绝对安全。最后也是最危险的一点,这么做会在剪贴板留下痕迹,而现在很多APP会监听剪贴板,你无法保证这些应用不含恶意代码。
1.添加代理密钥
1 | $ ssh-add -K ~/.ssh/id_rsa |
2.使用Agent
1 | $ ssh -A root@remotehost |
翻开
1 |
|
或者,在
1 | Host Robert |
Chrome插件商店即将全面停止对 manifest v2版本清单的支持,也就促使开发者们将逐渐将插件向MV3迁移。但迁移中会遇到的一些问题,比如清单格式的改变,由数组变成对象,或者由对象变成数组,不过这些问题也只是算格式上的不兼容而已,很好修改。而一些大麻烦比如MV3中CSP的策略更加严格,不仅限制了脚本注入,更是完全禁止使用
我在content.js中生成了一个script标签,并手动将其注入到页面中,如下:
1 | // content.js |
作为结果,你会发现:
对于这种情况,我们只需要将上面的js代码单独写到一个文件中,并在清单中声明此文件,方便Google进行代码审查,这样就满足MV3的要求了
1 | // inject.js |
1 | // content.js |
1 | // manifest.json |
由于Vue使用了
使用沙盒的好处是很明显的,比如原先使用Vue写的页面不需要修改就可继续使用,减少迁移的工作量。但是坏处也很明显,比如说在沙盒中无法调用插件相关的api,但其实这个问题也非常好解决,我们只需要在原来的插件环境和隔离出的沙盒环境中,添加一个数据交换的中间层就可以了。
1 | <!-- sandbox.html --> |
1 | <!-- warpper.html --> |
1 | // manifest.json |
接下来,我们在需要添加一个中间层,让
1 | // sandbox.js |
1 | // wrapper.js |
由于发送和接收数据是异步进行的,所以我们要对上面的方法按照发布-订阅的设计模式进行封装,以便让业务代码不需要大幅度修改即可使用
譬如在MV2中的代码:
1 | // sandbox.js |
对象
1 | // sandbox.js |
1 | // warpper.js |
如此,利用一个订阅—发布的中间件,我们不需要对代码进行大幅度修改,即可将插件迁移至MV3
建站的人,必定会使用到的一个工具——Nginx,大家或多或少都了解Nginx的一些特性,比如用作负载均衡服务器,再比如更常见的——在同一台主机上挂载好几个App,然后通过Nginx来匹配分流。
大部分时候,我们写Nginx配置时都是这样的,例如:
1 |
|
不是说同一个端口只能由一个程序使用吗,为什么这里监听了3个程序,Nginx还能正常工作?
其实我们在使用Nginx时,大部分时候是使用了它的http模块,而上面的三个
1 | http { |
而
而如果我们只是单纯的想要转发TCP流量(它可能也是HTTP流量)到下级应用时,那么使用http模块就无法满足我们的要求,就需要添加stream模块支持到Nginx中,通常它在Nginx中是默认不开启的,需要手动在 /path/to/nginx.conf 中添加以下配置:
1 | # nginx.conf |
这样就启用了stream模块,stream模块的工作方式可参考下图:
它的工作模式和http模块很相似,也是通过侦听端口+SNI匹配的形式来完成应用的分流。但是注意,stream模块和http模块不能侦听同一个端口,这两个模块应该被看作是互相独立的应用,也就是说,上图中通过stream模块进行监听了443端口,那么http模块就无法再监听443端口了,但是对于浏览器前端而言,他们仍可通过443端口访问到位于http模块下挂载的app(a.com)
一个stream配置的例子:
1 | stream { |
由于众所周知的原因,国内的云存储服务不再可靠。但是我在过往中大量的使用了七牛云的外链,所以需要将七牛中的文件保存起来。
在海外vps或者国内服务仍然可用的情况下,使用七牛的SDK批量备份文件,代码如下:
1 | # -*- coding: utf-8 -*- |
由于使用了多线程,大量访问可能会导致七牛云拒绝响应,或者下载超时,控制台会打印出失败的文件,需要手动处理,例如:
1 | <urlopen error retrieval incomplete: got only 1048576 out of 1592895 bytes> |
注:如果大量失败,需要手动调整代码以适用于不同的需求。
B2Cloud免费用户有10G存储空间和1G/天的流量,虽然1G流量看起来很少,但是套上CDN以后基本是用不完的。
B2Cloud提供了方便的CLI工具,备份文件可使用CLI上传,亦可以使用PicGo+B2上传插件上传,前者适用于VPS用户,而后者有GUI。
1.基于Python版本的B2 CLI
1 | $ pip3 install --upgrade b2 |
或者下载对应平台的可执行文件,点这里查看下载页
2.B2 Auth
输入命令,并按照提示输入KeyId和AppKey
1 | $ b2 authorize-account |
如何获取Id和Key,见下图:
3.上传文件
1 | $ b2 upload-file <your_bucket_name> <local_file_name> "<prefix>/<file_name>" |
1.安装PicGo
2.安装B2上传插件
虽然现在可以访问存储桶内的资源了,但速度慢如蜗牛,加上B2提供的外链丑陋,都是不想使用它的理由。而且如果直接使用B2外链,那么之前使用的cdn链接则处于失效状态。所以套接一个CDN网络很重要。
Backblaze可以使用Cloudflare加速,并且官方出了教程,详见:https://help.backblaze.com/hc/en-us/articles/217666928-Using-Backblaze-B2-with-the-Cloudflare-CDN
另外使用CF的边缘网络进行URL重写(或者Workers),可以去掉冗余的/file/
https://cdn.evink.cn/file/test-bucket/picgo/20220423172558.png —-> https://cdn.evink.cn/picgo/20220423172558.png
相较于Cloudfalre,CloudImage更专注于提供于图片分发服务,它有多达32种的预处理图片格式和每个月25G的免费流量和图片缓存,虽然CF也提供这些功能,但是CF需要额外收费,所以CloudImage是一个非常友好的替代品。
CloudImage使用也非常简单,它会提供一个token给你,然后你就可以加速互联网上的任意图片资源了。例如:
Cloudimage链接 https://
上面两个链接均指向此图:
这两个链接会指向同一张图片,当然CloudImage可设置
除此之外,CloudImage还提供图片预处理功能,本站的相册之前一直使用的七牛云的预处理功能,迁移至CloudImage之后,只需少量的修改后便可以继续使用。而且CloudImage提供了alias,以缩短图片链接。
原图: https://img.evink.cn/light/fullsizeoutput_30b.jpeg
上面两个链接均指向此图:
CF和CloudImage既可以单独使用,亦可以相互结合使用,更多功能不在此赘述。
展开 >>网上有很多例子都太过复杂了,其实只要观察文件的最后修改时间是否变动,就能判断文件是否变化了
1 | # Runtime: Python 3.9.6 |
需要Android SDK但不需要Android Studio?
https://developer.android.com/studio#command-tools
1.将解压缩后的文件夹更名为
2.按照以下结构创建文件树,或参考这里
1 | ┌ android-sdk |
特别地,针对Flutter使用者,执行以下命令来移除 “[✗] Android toolchain” 的错误:
1 | $ flutter doctor |
上次说到CF的worker可以做很多事,比如从第三方服务拿数据,再把数据写到Response中,我用了“重定向”这个词,其实不是很精确。
因为真正的重定向是这么写的:
1 | const { pathname, search } = new URL(event.request.url) |
而上次用的其实是Fetch模式,那借用这个模式,还可以做一些其他的事情。比如我们都知道自Chrome 81版本以来,会强制将浏览器中的Http协议的媒体资源改写为https协议,如果你的云存储用Https安全链接比较贵,那么这时,边缘计算网络就可以帮到你了:
1 | let response = await fetch(host + pathname + search) |
它可以拦截Https请求,在返回http资源给网页,而这一切,Chrome浏览器将无从得知。
当初Chrome团队决定将Http协议改写为Https协议时,是为了提高端对端的安全性。他们的解释是,Http协议的图片很容易通过攻击而被改写。比如你连上一个钓鱼用的WI-FI网络,攻击人可以通过请求拦截的形式修改任何的明文内容,而升级到Https则可避免这一点。
那在CloudFlare的边缘计算网络中将Https请求改写为Http时,会有安全问题吗?
我个人认为是比较安全的
浏览器 ----HTTPS----边缘计算网络 ----HTTP----原始目标
从连接模型上来看,浏览器到边缘网络是安全的Https协议,被攻击的可能性不大。从边缘网络到原始目标请求使用Http协议,这意味着安全工作交给了CloudFlare,如果CloudFlare所在的机房被攻击了,那么此方式才存在被人攻击的可能。
所以,对于数据安全很重要的网站而言,不应该使用此方式。而对媒体数据没那么敏感的网站(如本站)而言,也没有太大的安全威胁。
不过请注意,使用此方式将HTTPS协议重写,将大幅度降低国内访问这些资源的速度。
我们不希望访问一些重复的资源时,边缘服务器反复发起请求到原始目标。将上面的代码改写为:
1 | const host = "https://cdn.evink.cn" |
tag:
缺失模块。
1、请确保node版本大于6.2
2、在博客根目录(注意不是yilia根目录)执行以下命令:
npm i hexo-generator-json-content --save
3、在根目录_config.yml里添加配置:
jsonContent: meta: false pages: false posts: title: true date: true path: true text: false raw: false content: false slug: false updated: false comments: false link: false permalink: false excerpt: false categories: false tags: true