Apache/Nginx伪静态匹配http://问题与解决

问题是这样的,我搭建了一个网站icon图标抓取的API接口,正常情况下对象的传参是通过$_GET['url']获取的,因此常规获取图标的地址应该是:

    http://domain.com/?url=zhangge.net

    或

    http://domain.com/?url=http://zhangge.net

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

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

②、当抓取某个网站的ico时,先通过Nginx或Apache判断是否存在缓存文件,如果存在就直接返回给浏览器,这样在没开启CDN的情况下,因为返回的是纯静态文件,浏览器将会自动缓存,也就是返回304状态,加载速度得到提升!

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

    http://domain.com/zhangge.net

    或

    http://domain.com/http://zhangge.net

这是之前写的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://的请求重写,去掉其中的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]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    
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=http://zhangge.net获取也是http:/zhangge.net,少一个斜杠!

今天鬼使神差的试了下伪静态中判断http:/,结果成功了!我擦原来要匹配http://,实际上是匹配http:/,少一个斜杠!真实匪夷所思,以前从来没遇到过!
所以上述2个伪静态规则应该如下编写:
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;
    
#将包含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]

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]

文章写的很??拢?导噬瞎丶?越馐途褪牵??ginx或Apache中要匹配请求url中的【http://】,应该是匹配【http:/】,也就是少写一个斜杠!大胆猜测匹配其他多个斜杠也应该是少一个斜杠。。。

好了,文章洋洋洒洒写了这么多,网站图标API也是成功搭建在万网免费虚拟主机上了。地址是http://seo.zgboke.com/geticon/ ,虽然是专门给中国博客联盟用的,但是如果你有图标调用需求,也可以在合理使用的前提下自由发挥。

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

http://seo.zgboke.com/geticon/zhangge.net

然后按下F12进入开发模式,定位到network(网络选项卡),多刷新一次就能看到304状态了:

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

304表示当前文件来自浏览器缓存,因为请求的文件和服务段的文件一致,不需要重复调取!

当然,本文写到的伪静态规则只是一部分,如果要实现CDN加速,那还得新增相应的规则,不过这都是后话了,等下次我在张戈博客分享这个网站图标抓取API源码的时候,会一并贴上,敬请期待!

时间: 2024-09-20 10:43:31

Apache/Nginx伪静态匹配http://问题与解决的相关文章

PHPwind 9升级后 nginx apache iis 伪静态配置

  PHPwind 9 正式版是一个非常不错的论坛系统,这里就不多宣传了.主要问题是很多之前的用户升级来发现变化很多,之前的伪静态也不能使用了,这里交给大家一个快速设计PW9的伪静态和PHPwind 8.7升级来后,如何使用继续使用以前的伪静态的方法. 官方只提供了新版的伪静态的设计方法,如图: 搜索伪静态,按照要求开启即可, Apache Web Server 配置 在www目录下自带了.htaccess文件,开启了rewrite后可直接使用,更改了格式后也无需更改这个文件内容. IIS配置

WordPress 伪静态规则配置(IIS/Apache/Nginx)

IIS伪静态规则 IIS 环境是 Windows 主机常用的服务器环境,新建一个 txt 文件,将下面的代码添加到文件中: [ISAPI_Rewrite] # Defend your computer from some worm attacks #RewriteRule .*(?:global.asa|default\.ida|root\.exe|\.\.).* . [F,I,O] # 3600 = 1 hour CacheClockRate 3600 RepeatLimit 32   # P

Nginx 502错误触发条件与解决办法汇总

Nginx 502错误触发条件与解决办法汇总 一些运行在Nginx上的网站有时候会出现"502 Bad Gateway"错误,有些时候甚至频繁的出现.有些站长是在刚刚转移到Nginx之后就出现了这个问题,所以经常会怀疑这是不是Nginx的问题,但事实上这是个误区. 以下是从张宴和Ayou的博客搜集整理的一些Nginx 502错误的排查方法,供大家参考: Nginx 502错误的原因比较多,是因为在代理模式下后端服务器出现问题引起的.这些错误一般都不是nginx本身的问题,一定要从后端找

apache nginx设置目录无执行权限的方法

apache nginx设置目录无执行权限的方法web服务有iis,apache,nginx,使用操作系统无非是windows or *nux    代码如下 复制代码 location ~ ^/upload/.*.(php教程|php5)$ { deny all; } 来看俩段通常对上传目录设置无权限的列子,配置如下:  代码如下 复制代码 <directory "/var/111cn.net/upload"> <filesmatch ".php"

iis/apache/nginx 提示No input file specified

(一)IIS Noinput file specified 方法一:改PHP.ini中的doc_root行,打开ini文件注释掉此行,然后重启IIS 方法二: 请修改php.ini 找到 ; cgi.force_redirect = 1 去掉前面分号,把后面的1改为0 即 cgi.force_redirect = 0 (二)apacheNo input file specified apache No input filespecified,今天是我们配置apache RewriteRule时出

apache rewrite-求善良人士帮帮我啊,apache的伪静态问题

问题描述 求善良人士帮帮我啊,apache的伪静态问题 RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{HTTP_HOST} ^(test).bbs.16paosao.com$ RewriteRule ^(.*)$ bbs.php [QSA,L] R 我想在地址栏里面输入test.bbs.16paosao.com就能重定向到 bbs.php

centos7中重启apache服务出现的问题,求解决啊

问题描述 centos7中重启apache服务出现的问题,求解决啊 解决方案 看起来是kill进程的时候找不到"",PS 看一下是否有apache的进程,是不是可以手动kill一下. 解决方案二: 我用systemctl start httd.service 都启动不了 解决方案三: apache的服务是不是安装,注册好了 解决方案四: 看看你的/etc/httpd/conf.d/wsgi-keystone.conf这个配置文件,是不是什么地方写错了? 确定没错的话,输入 system

Apache/Nginx+PHP+MySQL一键环境安装包

windows平台 1.Nginx PHP环境集成包: http://www.upupw.net/Nginx/     我用的就是这个,WIN平台搞开发 Apache PHP环境集成包:http://www.upupw.net/Apache/ 2.WINDOWS的NGINX+PHP+MYSQL+MEMCACHED的服务器集成环境 http://www.hdj.me/wnmpserver LINUX 平台 1.linux+apache/nginx+php+mysql lanmp/lamp/lnmp

apache rewrite_module 伪静态与 Order allow,deny 封IP

apache  rewrite_module 伪静态与 order allow,deny  封ip 一 打开 apache 的配置文件 httpd.conf . 二 将#loadmodule rewrite_module modules/mod_rewrite前面的#去掉 三 在 httpd.conf中添加: <ifmodule mod_rewrite.c>     rewriteengine on     #rewritecond %{env:script_url} (?:index|dis