小程序在展现外链的源过多,并且地址不必定是https的,而小程序强制要求是https的,考虑使用OSS的回源功能,可是阿里的oss只能设置5个源。因而在中间加了一层将阿里云OSS 指向一台 ECS 的 Nginx 上作反向代理,配置以下:html
server { listen 80 default_server; listen [::]:80 default_server; server_name localhost; # 不加上这句,部分域名会没法解析 resolver 119.29.29.29 1.1.1.1; # 须要经过 –with-http_gunzip_module 参数启用 # 加上这句若是图片被强制 gzip 压缩,nginx 会解压再返回解压后的内容,这样阿里云 OSS 不会报「图片格式不支持」的异常 gunzip on; # 关闭 gzip 压缩 gzip off; location / { # 直接取 「 ?」 后面部分当作图片原来的 url 去请求 proxy_pass $args; }
访问地址格式以下python
http://{bucket.domain}/{any_filename}.png?http://t07img.yangkeduo.com/images/2018-03-05/7263a4942abe93040c316e99b1044510.png
例子nginx
http://xxxxx.oss-cn-hangzhou.aliyuncs.com/xxxxx.png?http://t07img.yangkeduo.com/images/2018-03-05/7263a4942abe93040c316e99b1044510.png
当咱们访问阿里云OSS 的连接时,若是没有在 Bucket 中找到文件,阿里云OSS 会在配置好的回源地址中将除本域名之外的路径部分去访问回源域名,这里是咱们的 Nginx 反向代理服务器[好比: 1.1.1.1],阿里云 OSS 会将地址转换为:小程序
http://1.1.1.1/xxxxx.png?http://t07img.yangkeduo.com/images/2018-03-05/7263a4942abe93040c316e99b1044510.png
Nginx 按照配置会取 URL 的 GET 参数部分(或说是 query), 变量为 $args 部分去访问图片的源地址,因而就变成了浏览器
http://t07img.yangkeduo.com/images/2018-03-05/7263a4942abe93040c316e99b1044510.png
注意:按照常规GET原本 「 ?」 部分后面应该是 key1=value1&key2=value2 这样的形式,这里用法比较另类, url 其实至关于 key 部分,这样 url 被带过就能够直接让 nginx 在不须要进一步处理就直接反向代理,理论上能够代理任何域名下的图片地址。缓存
将获取到的图片内容直接返回给 OSS,OSS 存储后再返回给客户端。整个过程都是同步的,若是服务器的带宽容许,延迟会比较小,并且在第二次请求时直接在 OSS 中读取。bash
这里遇到部分图片外链域名没法解析的状况须要加上服务器
resolver 119.29.29.29 1.1.1.1;
由于已经带?了因此再使用 ?x-oss-process=style/stylename
就不合适了,若是放在 上一个 ? 以前会让 Nginx 报 404 由于变成了 ?x-oss-process=style/stylename?http://xxxx.com/img.png
很明显这不是一个 url 了,若是放在后面会当值图片处理参数失败。这时候就须要用到 OSS 的 「规则名称」 使用形如 !_w100 这样的完美解决。如此地址就变成了dom
http://{bucket.domain}/{any_filename}.png!_w100?http://t07img.yangkeduo.com/images/2018-03-05/7263a4942abe93040c316e99b1044510.png
回源时图片加上图片处理参数会返回 ‘The Image Fomatter Is Not Supported’ 错误,可是查明阿里云明明是支持的这时就考虑是不是图片的编码出现了问题通过排查发现,咱们拿浏览器去请求时 Request 头会带上 Accept-Encoding: gzip 字段,这是 Response 就会开启 Content-Encoding: gzip 此时的图片是被压缩过的,若是 Nginx 不作处理就会致使 OSS 存储下来的图片没法被处理阿里云
判断图片是否有压缩, 使用 python-magic 同时在 mac 上用安装 libmagic,这个库是用来看文件类型的。
# mac 须要安装支持库 brew install libmagic # python 库 pip intall python-magic import magic magic.from_file('xxxxx.png') # 'gzip compressed data, last modified: Wed Apr 3 11:34:22 2019, from Unix, original size 55202'
Linux 可使用 file 来判断文件类型可是没法判断是否压缩文件
file 'xxx.png'
解决方法有二: