指引网

当前位置: 主页 > 服务器 > Nginx >

Apache 文件不存在跳转URL(实现指定尺寸的图片不存在,就自动生成图片)

来源:网络 作者:佚名 点击: 时间:2017-08-02 23:30
[摘要] 前言在做很多系统的时候,我们可能都有这样的需求:在CMS中只维护一张图片,而这张图片在网站的很多地方都需要显示,而且显示的大小不同。...

前言

在做很多系统的时候,我们可能都有这样的需求:

在CMS中只维护一张图片,而这张图片在网站的很多地方都需要显示,而且显示的大小不同。

一般做法就是直接使用这张图片,在不同的地方使用 width 和 height 设定图片的显示大小。

 

场景需求

一般情况下这样做其实就可以了。如下这个场景,如果通过这样做,可能就不太合适了。

场景:CMS 有个海报管理功能,每个大的海报都是一张 1000*2000px 的图片,而且对海报的清晰度有一定的要求,质量不能太差,假定一个海报有 1MB。

然后在网站上有一个海报列表,每页显示20个海报。

这种情况下如果我们还用一张图片,通过 width 和 height 来设定图片显示大小的话,那就太不合适了,一个列表页面下来,20多MB没有了。页面显示肯定会很慢。

 

解决思路

我们一般的做法有:

1、在CMS中上传一个海报大图,再上传一个海报小图。

2、在CMS中上传一个海报大图,保存的时候,系统自动生成一个海报小图。

3、在CMS中上传一个海报大图,在网页请求图片的时候,附带需求图片的 width 和 height,程序自动判断需求图片是否存在,如果不存在则使用对应的大图生成一个图片响应到客户端。

 

上面三种做法,1、2 两种情况不够灵活,如果系统还有更多地方需要显示不同尺寸的这样的图片呢?或者系统二期、三期……扩展的时候也有可能有更多尺寸的图片需求呢?

至于第三种方法,相对比较灵活,只有在我们需要的时候才生成。

 

我们现在需要使用 Apache 来处理我们的静态图片资源。一般情况下 Apache 可不会去管你的图片存在不存在,当我们访问一个新的尺寸图片时,服务器上不存在图片文件,Apache 就直接响应404了。

现在我们要做的就是,让Apache 来判断文件是否存在,如果文件不存在就转而请求我们生成图片的请求。

这样以来,每个尺寸的图片,在需求的时候,第一次 Apache 会交给我们的程序去生成图片,以后这个图片存在了,就全部由Apache 自己管理了。

 

Apache 配置

下面来说一下 Apache 怎么配置,来实现 “当文件不存在的时候,转发请求到处理程序”。

1、开启 rewrite 模块

      去除httpd.conf文件中 #LoadModule rewrite_module modules/mod_rewrite.so 前面的"#"号

2、在 httpd.cnf 中增加配置(没有位置要求,一般我们放在文件最后即可)

      我是用的是 apache 2.4 的 VirtualHost ,图片处理程序是用的 Tomcat,所以也给Apache 添加了mod_jk 模块(这个本文不做讲解,可以查看帖子 http://blog.csdn.net/catoop/article/details/47974773)

      需要添加的配置内容为:
 

  1. <span style="font-family:Microsoft YaHei;font-size:12px;">        <IfModule mod_rewrite.c> 
  2.                 RewriteEngine On 
  3.                 # '-s' (is regular file, with size) 
  4.                 # '-l' (is symbolic link) 
  5.                 # '-d' (is directory) 
  6.                 # 'ornext|OR' (or next condition) 
  7.                 # 'nocase|NC' (no case) 
  8.                 # 'last|L' (last rule) 
  9.                 # 'QSA' 追加请求字符串 
  10.  
  11.                 RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-s 
  12.                 RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-l  
  13.                 RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f 
  14.  
  15.                 #RewriteRule ^(.*)\.[jpg|png|bmp]$ %{HTTP_HOST}/createimage.jsp?path=%{REQUEST_URI} [NC,L] 
  16.                 #RewriteRule ^(.*)\.(jpg|png|bmp)$ createimage.jsp?path=%{REQUEST_URI} [NC,L] 
  17.                 RewriteRule ^(.*)\.(jpg|png|bmp)$ http://shanhyweb.example.com/createimage.jsp?path=%{REQUEST_URI} [NC,L] 
  18.                 #RewriteRule ^(.*)\.(jpg|png|bmp)$ /createimage.jsp?path=%{REQUEST_URI} [NC,L] 
  19.  
  20.         </IfModule></span> 

   配置可以直接在 httpd.cnf 中添加,也可以在 VirtualHost  中配置,因为我使用的是 VirtualHost 所以我的配置是在 apache2/conf/extra/httpd-vhosts.conf 中,如下:

 

  1. <span style="font-family:Microsoft YaHei;font-size:12px;">######################################################## 
  2. LoadModule jk_module modules/mod_jk.so 
  3. Include conf/mod_jk.conf 
  4. ######################################################## 
  5. <VirtualHost *:80> 
  6.     #ServerAdmin webmaster@dummy-host.example.com 
  7.     DocumentRoot "/svcroot/runtime/webstatic/shanhyweb" 
  8.     ServerName shanhyweb.example.com 
  9.     #ServerAlias www.shanhyweb.example.com 
  10.     ErrorLog "logs/shanhyweb-error_log" 
  11.     CustomLog "logs/shanhyweb-access_log" common 
  12.         <IfModule mod_jk.c> 
  13.                 #日志输出文件(其他配置也可以重写mod_jk.conf里面的配置) 
  14.                 JkLogFile logs/mod_jk_shanhyweb.log 
  15.                 #指URL指向如果有servlet,则让worker_web去处理 
  16.                 JkMount /servlet/* worker_web 
  17.                 #指URL为/*.jsp的页面,让worker_web去处理 
  18.                 JkMount /*.jsp worker_web 
  19.                 #指URL为/*.do的页面,让worker_web去处理 
  20.                 JkMount /*.do worker_web 
  21.                 #指URL为/*.json的页面,让worker_web去处理 
  22.                 JkMount /*.json worker_web 
  23.         </IfModule> 
  24.  
  25.     <IfModule mod_rewrite.c> 
  26.         RewriteEngine On 
  27.         # '-s' (is regular file, with size)  
  28.         # '-l' (is symbolic link)  
  29.         # '-d' (is directory)  
  30.         # 'ornext|OR' (or next condition)  
  31.         # 'nocase|NC' (no case)  
  32.         # 'last|L' (last rule)  
  33.         # 'QSA' 追加请求字符串 
  34.  
  35.         RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-s  
  36.         RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-l  
  37.         RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f 
  38.  
  39.         RewriteRule ^(.*)\.(jpg|png|bmp)$ http://shanhyweb.example.com/createimage.jsp?path=%{REQUEST_URI} [NC,L] 
  40.  
  41.     </IfModule> 
  42.  
  43.         <Directory "/svcroot/runtime/webstatic/shanhyweb"> 
  44.                 Options FollowSymLinks 
  45.                 AllowOverride None 
  46.                 Require all granted 
  47.         </Directory> 
  48. </VirtualHost></span> 

注意:生成图片的这个处理,对同一个图片处理那段代码要做好加锁或同步处理,防止出现高并发情况下,读取和生成图片因为资源占用而出问题的情况。

 
------分隔线----------------------------