最近感觉小米盒子越来越卡,然后网上查一下什么电视盒子性能比较好。结果发现很多人推荐N1盒子,性价比极高,可玩性极强。然后就在拼多多上找到下单了,110块加个T1遥控器减掉优惠算下来125块。注意如果家里没有双公头数据线的话,在购买盒子的时候勾选有双公头刷机线的套餐即可。

2019年,在三年不涨工资快要活不下去的情况下,终于涨了些许工资,每月还完贷款后总算有点余粮。但是要买的东西太多,换上了5G手机(家里已经有5G信号覆盖,但是平时不怎么用,用得最多就是测网速),嫌15年的MBP打包太慢(基本在半个小时左右),咬牙分期换了最新的16寸MBP。。。钱永远不够花。。。
附上2019部分拔草清单:

  • 希捷4TB移动硬盘
  • 1.05米书桌
  • 1.2米书桌
  • 西门子640TI洗碗机
  • 树莓派4B
  • ikbc w210
  • AOC 32寸 4K 曲面显示器
  • Mate 30 Pro 5G
  • MacBook Pro 16寸

2020愿望清单:

  • 草缸 (基础大件已买,过年回来开缸)
  • NAS
  • 耳机

似乎每年初总会循例定一下年度目标,但是没有一年能够实现的😄。所以今年不打算立Flag了,健健康康、开开心心就好!

最后,祝所有人身体健康!

最近在写一个下载图片的爬虫,跑了一段时间,中间操作不慎删除了部分图片,于是重新下载,发现两次下载的图片大小不一样。
于是分析了一波,最后在 response headers 上发现 cf-bgjcf-polishedcf-cache-status 这些字段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{ date: 'Mon, 03 Dec 2018 09:06:53 GMT',
'content-type': 'image/jpeg',
'content-length': '775327',
connection: 'keep-alive',
'cache-control': 'public, max-age=31536000',
'cf-bgj': 'imgq:85',
'cf-polished': 'degrade=85, origSize=2376032',
etag: '"5b0646f6-244160"',
expires: 'Tue, 03 Dec 2019 09:06:53 GMT',
'last-modified': 'Thu, 24 May 2018 05:00:38 GMT',
vary: 'Accept',
'cf-cache-status': 'HIT',
'accept-ranges': 'bytes',
'expect-ct': 'max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"',
server: 'cloudflare',
'cf-ray': '4834e13b29efa2fc-HKG' }

挑重点

1
'content-length': '775327', 'cf-bgj': 'imgq:85','cf-polished': 'degrade=85, origSize=2376032', cf-cache-status': 'HIT'

也就是说原图大小是 2376032 ,下载下来的只有 775327

查阅 Cloudflare 官方这篇文件:
https://support.cloudflare.com/hc/en-us/articles/360000607372-Using-Polish-to-compress-images-on-Cloudflare

文章上面介绍cloudflare有两种压缩方式,一种是无损压缩:

Only strips metadata, e.g. EXIF data, but doesn’t change the image

仅剥离元数据,例如EXIF数据,但不更改图片。
实质上,这种无损压缩也可能会使图片颜色失真,参考这篇文章:
https://pwmon.org/p/5470/cloudflare-discolors-web/

另一种是有损压缩:

Strips metadata and Compresses image to ~”85%”

删除元数据并压缩图片

即无论那种压缩,或多或少都会对图片造成失真。

方案

尝试一种方法是使用缓存控制,设置 request headers 的 Cache-Control: no-cache, no-store, no-transform,但是发现还是返回了 cf-cache-status': 'HIT',似乎不生效。

尝试另一种更简单的方式,向URL添加随机伪参数以防止缓存命中,
如在 URL 后添加时间戳:

1
https://xxx.com/xxx.jpg?_=1543834270359

问题解决!

安装

安装很简单, 一个命令:

1
curl  https://get.acme.sh | sh

并创建 一个 bash 的 alias, 方便你的使用:

1
alias acme.sh=~/.acme.sh/acme.sh

配置对应域名解析API(以阿里云为例)

https://github.com/Neilpang/acme.sh/blob/master/dnsapi/README.md

获取阿里云API key:
https://usercenter.console.aliyun.com/#/manage/ak
得到:
AccessKeyID:*****隐藏敏感信息****
AccessKeySecret:*****隐藏敏感信息****

1
2
export Ali_Key="*****隐藏敏感信息****"
export Ali_Secret="*****隐藏敏感信息****"

生成证书

1
acme.sh --issue --dns dns_ali -d jeepeng.com -d *.jeepeng.com

这里给出的 Ali_KeyAli_Secret会被自动记录在 ~/.acme.sh/account.conf 文件中,到时候会自动调用.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[Mon Oct 29 12:13:44 CST 2018] Registering account
[Mon Oct 29 12:13:46 CST 2018] Registered
[Mon Oct 29 12:13:46 CST 2018] ACCOUNT_THUMBPRINT='*****隐藏敏感信息****'
[Mon Oct 29 12:13:46 CST 2018] Creating domain key
[Mon Oct 29 12:13:46 CST 2018] The domain key is here: /root/.acme.sh/jeepeng.com/jeepeng.com.key
[Mon Oct 29 12:13:46 CST 2018] Multi domain='DNS:jeepeng.com,DNS:*.jeepeng.com'
[Mon Oct 29 12:13:46 CST 2018] Getting domain auth token for each domain
[Mon Oct 29 12:13:48 CST 2018] Getting webroot for domain='jeepeng.com'
[Mon Oct 29 12:13:48 CST 2018] Getting webroot for domain='*.jeepeng.com'
[Mon Oct 29 12:13:48 CST 2018] Found domain api file: /root/.acme.sh/dnsapi/dns_ali.sh
[Mon Oct 29 12:13:50 CST 2018] Found domain api file: /root/.acme.sh/dnsapi/dns_ali.sh
[Mon Oct 29 12:13:52 CST 2018] Sleep 120 seconds for the txt records to take effect
[Mon Oct 29 12:15:54 CST 2018] Verifying:jeepeng.com
[Mon Oct 29 12:15:57 CST 2018] Success
[Mon Oct 29 12:15:57 CST 2018] Verifying:*.jeepeng.com
[Mon Oct 29 12:16:00 CST 2018] Success
[Mon Oct 29 12:16:00 CST 2018] Removing DNS records.
[Mon Oct 29 12:16:06 CST 2018] Verify finished, start to sign.
[Mon Oct 29 12:16:09 CST 2018] Cert success.
-----BEGIN CERTIFICATE-----
*****************隐藏敏感信息*******************
-----END CERTIFICATE-----
[Mon Oct 29 12:16:09 CST 2018] Your cert is in /root/.acme.sh/jeepeng.com/jeepeng.com.cer
[Mon Oct 29 12:16:09 CST 2018] Your cert key is in /root/.acme.sh/jeepeng.com/jeepeng.com.key
[Mon Oct 29 12:16:09 CST 2018] The intermediate CA cert is in /root/.acme.sh/jeepeng.com/ca.cer
[Mon Oct 29 12:16:09 CST 2018] And the full chain certs is there: /root/.acme.sh/jeepeng.com/fullchain.cer

Copy 证书

1
2
3
4
acme.sh  --installcert  -d  jeepeng.com   \
--key-file /etc/nginx/ssl/jeepeng.com.key \
--fullchain-file /etc/nginx/ssl/jeepeng.com.fullchain.cer \
--reloadcmd "service nginx force-reload"

配置nginx

1
2
ssl_certificate /etc/nginx/ssl/jeepeng.com.fullchain.cer;
ssl_certificate_key /etc/nginx/ssl/jeepeng.com.key;

react native webview加载本地html资源文件的解决方案

需求

  • release可以工作(这个是必须的)
  • 可以传query参数(暂不考虑其它方式实现传参)

测试环境

  • macOS 10.12.3
  • react-native v0.42

尝试方案1

1
const source = reuqire('./index.html');

工作情况:

- android ios
debug ok ok
release not work ok

缺点:

  • 不能带query参数

结论:android只能在debug模式下使用,不可行。

尝试方案2

1
const source = Platform.OS === 'ios' ? require('./index.html') : { uri: 'file:///android_asset/index.html' };

工作情况:

- android ios
debug not work ok
release ok ok

缺点:

  • ios不能带query参数

结论:release可行,但是ios端不能传参数。如果没有传参数需求,用这个方案即可
如果想同时在android的debug环境下工作,根据__DEV__的值加个判断即可

尝试方案3

1
2
3
4
5
6
7
import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource';

const _source = resolveAssetSource(require('./index.html'));
const source = Platform.select({
android: { uri: `file:///android_asset/index.html?id=${article.id}` },
ios: { uri: `file://${_source.uri}?id=${article.id}` },
});

工作情况:

- android ios
debug not work not work
release ok ok

结论:release可行,可传参数!如果想同时在debug下工作,根据__DEV__的值加个判断即可

最终可行方案

普通方案:

一般情况下使用这个方案即可:

1
2
3
4
5
6
let source;
if (__DEV__) {
source = require('./index.html');
} else {
source = Platform.OS === 'ios' ? require('./index.html') : { uri: 'file:///android_asset/index.html' };
}

可传query方案:

可在uri后面加上query参数,如:path/to/file.html?page=1&page_size=10

1
2
3
4
5
6
7
8
9
10
11
import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource';

let source;
const _source = resolveAssetSource(require('./index.html'));
if (__DEV__) {
source = { uri: `${_source.uri}&id=${article.id}` };
} else {
const sourceAndroid = { uri: `file:///android_asset/index.html?id=${article.id}` };
const sourceIOS = { uri: `file://${_source.uri}?id=${article.id}` };
source = Platform.OS === 'ios' ? sourceIOS : sourceAndroid;
}

工作情况:

- android ios
debug ok ok
release ok ok

render:

1
<WebView source={source}  {...props} />

注意事项

  • 以上html的路径根据自己的项目情况进行修改
  • [android] react-native bundle时会把html文件当成drawable资源,请手动把android/res/drawable中的html文件删除,否则build时会报错
  • 打包时候要手动把html和相关的css、js拷到对应的目录中,如
    [android]: android/app/src/main/assets/
    [ios]: ios/assets

转载需注明出处:https://blog.jeepeng.com/2017/react-native-webview-load-from-device-local-file-system/