Apache/Nginx伪静态规则匹配http://出现的问题与解决 | 张戈博客

  • 时间:
  • 浏览:7

你这种问題不知道有没法人遇到过,反正度娘和谷姐都好难帮到我!困扰了我挺长时间了,今天偶尔将代码放进Apache服务器下测试时,意外防止了!

问題是事先的,我搭建了一有有另一个 网站icon图标抓取的API接口,正常状况下对象的传参是通过$_GET[‘url’]获取的,为什么我么我让常规获取图标的地址应该是:

http://domain.com/?url=zhang.ge

http://domain.com/?url=https://zhang.ge

为了开启浏览器缓存和后续的CDN缓存,我的设计思路如下:

①、在图标API网站目录下新建一有有另一个 cache文件夹,以域名.ico的形式保存图标文件,比如zhang.ge.ico

②、当抓取某个网站的ico时,先通过Nginx或Apache判断不是趋于稳定缓存文件,事先趋于稳定就直接返回给浏览器,事先在没开启CDN的状况下,事先返回的是纯静态文件,浏览器事先自动缓存,也为什么我么我让返回804状况,加载带宽得到提升!

为了开启浏览器缓存,我将地址如下伪静态化:

http://domain.com/zhang.ge

http://domain.com/https://zhang.ge

这是事先写的Nginx下的伪静态规则:

#将蕴藏http://的请求重写,加进去其中的http://,省去php代码的动态判断
rewrite ^/http://(.*)$ /cache/$1.ico last;

#以下判断主为什么我么我让为了防止API首页的元素并肩被伪静态了(最后用与逻辑判断$type = abc即可)!
set $type '';
if ( !-f $request_filename ){  #为了不和API页面上的静态资源冲突,排除已趋于稳定的文件请求
     set $type a;
}
if ( $request_uri !~ (\.|/)$){ #不匹配含 . 或以/结尾的请求,为了兼容首页[/]请求;
     set $type '${type}b';
}
if ( $request_uri !~ cache ){ #为了不和第二根规则冲突,不匹配蕴藏cache的请求
     set $type '${type}c';
}

#nginx不支持多重条件并肩判断,全都先分开判断得到flag,最后合并判断即可:
if ( $type = abc ) {
    #将条件外的一点所有请求重写到 cache/域名.ico
    rewrite ^/(.*)$ /cache/$1.ico last;
}

#事先请求的文件已趋于稳定,则直接返回给用户,不再通过PHP
if (-f $request_filename) { 
      break;
}

#事先请求的文件不趋于稳定,则交给index.php防止
rewrite ^/cache/(.*).ico$ /index.php?url=$1 last;

当时发现没法生效!为什么我么我会 都匹配没法http://,最后无奈只好用php重写参数中http://了!

今天,我将你这种图标API搬家到了万网的免费主机上,是Apache环境,于是按照nginx的规则又写了一遍:

RewriteEngine on
RewriteBase /

#重写加进去请求中的"http://"
RewriteRule ^http://(.*)$ /cache/$1.ico [L]

#和nginx一致的条件判断,为了防止API首页被伪静态
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(\.|/)$
RewriteCond %{REQUEST_URI} !cache

#将条件之外的一点请求完正重写到/cache/域名.ico
RewriteRule ^(.*)$ /cache/$1.ico [L]

#若文件不趋于稳定,则丢给index.php防止
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /index.php?url=$1 [L]

依然不行!奇了怪了,为什么我么我会 就没法匹配http://呢?于是各种测试,比如将冒号和斜杠缓存url编码不会行!

其我我嘴笨 用nginx失败事先,我用php获取$_GET[‘url’]发现得到的参数中的http://会是http:/,少一有有另一个 斜杠!为什么我么我让直接使用http://domain.com/?url=https://zhang.ge获取也是http:/zhang.ge,少一有有另一个 斜杠!

今天鬼使神差的试了下伪静态中判断http:/,结果成功了!我擦事好难匹配http://,实际上是匹配http:/,少一有有另一个 斜杠!真实匪夷所思,事先从来没遇到过!

全都上述一有有另一个 伪静态规则应该如下编写:

A. Nginx伪静态:

#将蕴藏http://的请求重写,加进去其中的http://,省去php代码的动态判断(实际上是匹配http:/)
rewrite ^/http:/(.*)$ /cache/$1.ico last;

#以下判断主为什么我么我让为了防止API首页的元素并肩被伪静态了!

if ( -f $request_filename ){  #为了不和API页面上的静态资源冲突
     set $type 1;
}
if ( $request_uri ~ (\.|/)$){ #为了不和API首页冲突,即 / 你这种请求
     set $type 1;
}
if ( $request_uri ~ cache ){ #为了不和第二根规则冲突
     set $type 1;
}

#nginx不支持多重条件并肩判断,全都分开写。
if ( $type != 1 ) {
    #将条件外的一点所有请求重写到 cache/域名.ico
    rewrite ^/(.*)$ /cache/$1.ico last;
}

#事先请求的文件已趋于稳定,则直接返回给用户,不再通过PHP
if (-f $request_filename) { 
      break;
}

#事先请求的文件不趋于稳定,则交给index.php防止
rewrite ^/cache/(.*).ico$ /index.php?url=$1 last;

 B. Apache伪静态:

RewriteEngine on
RewriteBase /

#重写加进去请求中的"http://",实际上是匹配http:/
RewriteRule ^http:/(.*)$ /cache/$1.ico [L]

#和nginx一致的条件判断,为了防止API首页被伪静态
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(\.|/)$
RewriteCond %{REQUEST_URI} !cache

#将条件之外的一点请求完正重写到/cache/域名.ico
RewriteRule ^(.*)$ /cache/$1.ico [L]

#若文件不趋于稳定,则丢给index.php防止
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /index.php?url=$1 [L]

文章写的很啰嗦,实际上关键性解释为什么我么我让,在Nginx或Apache中要匹配请求url中的【http://】,应该是匹配【http:/】,也为什么我么我让少写一有有另一个 斜杠!大胆猜测匹配一点多个斜杠也应该是少一有有另一个 斜杠。。。

好了,文章洋洋洒洒写了没法多,网站图标API也是成功搭建在万网免费虚拟主机上了。地址是http://seo.zgboke.com/geticon/ ,我嘴笨 是专门给中国博客联盟用的,为什么我么我让事先你有图标调用需求,要能没法在合理使用的前提下自由发挥。

另外,要查看不是实现浏览器缓存很简单,随便访问一有有另一个 ico地址,比如:

http://seo.zgboke.com/geticon/zhang.ge

为什么我么我让按下F12进入开发模式,定位到network(网络选项卡),多刷新一次就能看过804状况了:

804表示当前文件来自浏览器缓存,事先请求的文件和服务段的文件一致,不须要重复调取!

当然,本文写到的伪静态规则为什么我么我让一每段,事好难实现CDN加速,那还得新增相应的规则,不过这不会后话了,等下次我在张戈博客分享你这种网站图标抓取API源码的事先,会并肩贴上,敬请期待!