基于nginx对discuz做301永久重定向的方法

工作室运维的区域性网站要做重大改版,向着门户型改变:

discuz 6.1升级7.0,ucenter 1.0升级1.5,uchome 1.5升级2.0,并将增加ecshop商城以及点评系统,论坛、空间、商城、点评四个系统采用uc统一管理,这样的话可以让产品更好地整合在一起。当然,卸载任何一个系统也不会影响另外系统的正常运行。

废话说完,进入正题

原网站真正意义上起到作用的就是一个bbs,而该bbs的网址类似www.abc.com/bbs

考虑到升级后将bbs作为主体来运维(表现形式类似19楼,跳出论坛的范围,走社区化道路),我建议采用根目录直接放置论坛系统,而其他几个系统放置在域名的二级目录,如下:

home.abc.com shop.abc.com dp.abc.com

一级目录相比较二级目录权重高,一级域名自然也比二级域名权重高。考虑到整体以discuz论坛作为重点,自然主次分明。而且划分出二级域名,也方便以后网站的分离和管理。

因为论坛入口从原先的www.abc.com/bbs变成了www.abc.com,如果直接这样搬迁,那么之前做的seo必然会丢失(google跟baidu找过来都是死链),可能导致seo的禁忌:大片网页删除甚至域名被K了。

那么我只要将之前在bbs目录下的规则以301永久重定向到根目录下就可以了,这样搜索引擎也不会“感冒”。

  1. #之前的目录跳转到现在的根目录 301 永久重定向 permanent; 
  2. rewrite ^/bbs/archiver/((fid|tid)-[\w\-]+\.html)$ /archiver/index.php?$1 permanent; 
  3. rewrite ^/bbs/forum-([0-9]+)-([0-9]+)\.html$ /forumdisplay.php?fid=$1&page=$2 permanent; 
  4. rewrite ^/bbs/thread-([0-9]+)-([0-9]+)-([0-9]+)\.html$ /viewthread.php?tid=$1&extra=page\%3D$3&page=$2 permanent; 
  5. rewrite ^/bbs/space-(username|uid)-(.+)\.html$ /space.php?$1=$2 permanent; 
  6. rewrite ^/bbs/tag-(.+)\.html$ /tag.php?name=$1 permanent; 
  7. #如果bbs下文件或目录不存在则重定向到index.php 
  8. #if (!-e $request_filename) { rewrite ^/bbs/(.*) /index.html?$1&; } 

检测下是否重定向成功了

301重定向后在线检测工具[HTTP头状态检测]:

http://www.seoconsultants.com/tools/headers.asp

如果某个网址是永久重定向301效果,则必然显示:HTTP/1.1 301 Moved Permanently


摘录1:网络

所谓301永久重定向(或叫301转向,301跳转),是指当用户或搜索引擎向网站服务器发出浏览请求时,服务器返回的HTTP数据流中头信息(header)中的状态码的一种,表示本网页永久性转移到另一个地址。

301永久重定向有何作用?在哪些情况下适用?

从301永久重定向的定义可以看出,它是一种状态码,会向搜索引擎或浏览器发出信息:本网页的地址已经永久改变了。并会把新的地址传达过去。而相应的就是:我们输入网址A访问,显示出来的是转向后的网址B,转向过程极短以至无法察觉。所以,301永久重定向对于访客来说,作用就是将他要访问的而实际上已不存在的网址转到另一个网址,避免出现“此网页无法显示”之类的错误;对于搜索引擎优化|SEO来说,给搜索引擎一个友好的信息,告诉它此页面已永久重定向,避免搜索引擎找不到页面。这对于网站的SEO是很重要的,因为301永久重定向对SEO无任何不好的影响!而且网页A的关键词排名和PR级别都会传达给网页B!

一、当出于需要删除网站中的某些目录时,可以通过301永久重定向将此目录重定向到网站首页。

二、网站更换域名时,通过301永久重定向将旧域名重定向至新域名,挽回流量损失和SEO。

三、想要多个域名同时指向同一网站时,通过301永久重定向可以实现。
一般的虚拟主机后台提供将test.cn和www.test.cn等多个域名绑定到同一网站的功能,但这样对收录可能有影响,而用301永久重定向就没有这样的担忧。

四、实现网址规范化。
有以下4个网址:
http://test.cn
http://www.test.cn
http://test.cn/index.html
http://www.test.cn/index.html
查询上面4个网址的PR值,或用site:test.cn查看网站首页,如果结果一致,说明网站没有规范化问题;如果不一致,表明有规范化问题。出现此问题时,可以将上面4个网址通过301永久重定向指向同一个网址http://www.test.cn,解决了。

如何实现301永久重定向?

一、通过代码实现301永久重定向。

HTML网页无法实现301永久重定向。因为HTML文件一被读取,就已经返回表示一切正常的200状态码了。

比如,你要删除某个目录A,想实现访问http://www.test.cn/A/时跳转到http://www.test.cnheader(”HTTP/1.1 301 Moved Permanently”);
header(”Location:http://www.test.cn”);
exit();
?>

访问http://www.test.cn/A/其实就是访问http://www.test.cn/A/index.php,就会自动跳转到http://www.test.cn

有个技巧:如果http://www.test.cn 网站目录下同时存在index.html和index.asp,设置文档优先级html>asp时,输入http://www.test.cn访问到的是http://www.test.cn/index.html;设置文档优先级asp>html时,访问的是http://www.test.cn/index.asp.

二、虚拟主机301永久重定向

如果你的网站空间是使用虚拟主机或合租空间,无法对WEB服务器(IIS、Apache)进行设置,可以利用子目录绑定实现301永久重定向。首先建立子目录A,然后把你要进行重定向的域名A绑到这个目录,在这个子目录里面建立一个index.php文件,写入上面介绍的代码。那么访问子目录A下的index.php也即访问域名A,就会跳转到绑定在其他子目录上的域名B。

三、Apache实现301永久重定向。

Apache中的分布式配置文件“.htaccess”提供了针对每个目录改变配置的方法,即在一个特定的目录中放置一个包含指令的文件,其中的指令作用于此目录及其所有子目录。比如,在目录A下放.htaccess,写入代码:

redirect 301 /A http://www.test.cn 或
redirect permanent /A http://www.test.cn

访问http://www.test.cn/A/及其子目录时即可重定向到http://www.test.cn。若将整个网站或域名重定向到另一网站或域名,则可写入redirect 301 / http://www.test.cn,将.htaccess放在根目录即可。

如果要实现“批量重定向”,比如,把http://test.cn/a.html重定向到http://www.test.cn/a.html,把http://test.cn/b.html重定向到http://www.test.cn/b.html。。。等等,即把http://test.cn下的所有文件重定向到http://www.test.cn下的同名文件,则要用到mod_rewrite模块。在.htaccess中写入:

Options +FollowSymLinks
RewriteEngine on
RewriteCond %{HTTP_HOST} ^test.cn [NC]
RewriteRule ^(.*)$ http://www.test.cn/$1 [L,R=301]

即可。

或将绑定的其他多个域名重定向到主域名:

RewriteEngine on
RewriteCond % ^test.cn$ [OR]
RewriteCond % ^bbs.test.cn$ [OR]
RewriteRule ^(.*)$ http://www.test.cn/ [R=301,L]
本篇文章来源于 - http://www.itokit.com - web开发技术 原文地址是:http://www.itokit.com/bbs/redirect.php?tid=11670&goto=lastpost


摘录2:网络

首先Apache的Rewite规则差别不是很大,但是Nginx的Rewrite规则比Apache的简单灵活多了
Nginx可以用if进行条件匹配,语法规则类似C


if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /msie/$1 break;
}

    Rewrite的Flags
    last - 基本上都用这个Flag。
    break - 中止Rewirte,不在继续匹配
    redirect - 返回临时重定向的HTTP状态302
    permanent - 返回永久重定向的HTTP状态301

    Wordpress的重定向规则:

if (!-e $request_filename) {
rewrite ^/(index|atom|rsd)\.xml$ http://feed.shunz.net last;
rewrite ^([_0-9a-zA-Z-]+)?(/wp-.*) $2 last;
rewrite ^([_0-9a-zA-Z-]+)?(/.*\.php)$ $2 last;
rewrite ^ /index.php last;
}

    以下为Discuz完整的Rewrite for Nginx规则

if (!-f $request_filename) {
rewrite ^/archiver/((fid|tid)-[\w\-]+\.html)$ /archiver/index.php?$1 last;
rewrite ^/forum-([0-9]+)-([0-9]+)\.html$ /forumdisplay.php?fid=$1&page=$2 last;
rewrite ^/thread-([0-9]+)-([0-9]+)-([0-9]+)\.html$ /viewthread.php?tid=$1&extra=page%3D$3&page=$2 last;
rewrite ^/space-(username|uid)-(.+)\.html$ /space.php?$1=$2 last;rewrite ^/tag-(.+)\.html$ /tag.php?name=$1 last;
}

    正则正则表达式匹配注解

~ 为区分大小写匹配
~* 为不区分大小写匹配
!~和!~*分别为区分大小写不匹配及不区分大小写不匹配
2、文件及目录匹配,其中:

-f和!-f用来判断是否存在文件
-d和!-d用来判断是否存在目录
-e和!-e用来判断是否存在文件或目录
-x和!-x用来判断文件是否可执行
 


摘录3:网络

静态地址重定向到带参数的动态地址

rewrite "^(.*)/service/(.*)\.html$" $1/service.php?sid=$2 permanent;


带参数的动态地址重定向到静态地址

if ($query_string ~* id=(.*)) {
    set $id $1;
    rewrite "^(.*)/article.asp$" $1/article/$id.htm last;
}

泛域名解析

server_name www.w3cgroup.com *.w3cgroup.com;
server_name_in_redirect off;
#设置默认root
set $rootdir /usr/local/nginx/html/w3cgroup/;
#匹配三级域名
if ($host ~* ^([^\.]+)\.([^\.]+)\.([^\.]+)\.([^\.]+)$) {
    set $rootdir /usr/local/nginx/html/w3cgroup/$2/$1;
    #三级域名中有访问指定的目录则重定向到相应的二级域名下
    rewrite "^.+upload/?(.*)$" http://upload.w3cgroup.com/$1 permanent;
    rewrite "^.+ijc/?(.*)$" http://ijc.w3cgroup.com/$1 permanent;
    break;
}
#匹配二级域名
if ($host ~* ^([^\.]+)\.([^\.]+)\.([^\.]+)$) {
    set $rs1 $1;
}
#设置www时root
if ($rs1 ~* ^www$) {
    set $rootdir /usr/local/nginx/html/platform_ig/;
    #二级域名中有访问指定的目录则重定向到相应的二级域名下,注意,这里要使用last
    rewrite "^.+upload/?(.*)$" upload/$1 last;
    rewrite "^.+ijc/?(.*)$" ijc/$1 last;
    break;
}
#设置非www二级域名时root
if ($rs1 !~* ^www$) {
    set $rootdir /usr/local/nginx/html/w3cgroup/$rs1;
    #二级域名中有访问指定的目录则重定向到相应的二级域名下
    rewrite "^.+upload/?(.*)$" http://upload.w3cgroup.com/$1 permanent;
    rewrite "^.+ijc/?(.*)$" http://ijc.w3cgroup.com/$1 permanent;
    break;
}
#应用root
root $rootdir;
index index.php index.html;
error_page 404 http://$host/;
 

注意:if () {} 之间需要空格,否则Nginx.conf会报unknow directive 错误!

参考:

Nginx Rewrite Flags
* last 相当于Apache里的[L]标记,表示完成rewrite
* break 终止匹配, 不再匹配后面的规则
* redirect 返回302临时重定向
* permanent 返回301永久重定向

Nginx正则表达式匹配
* ~ 为区分大小写匹配
* ~* 为不区分大小写匹配
* !~和!~*分别为区分大小写不匹配及不区分大小写不匹配

Nginx文件及目录匹配
* -f和!-f用来判断是否存在文件
* -d和!-d用来判断是否存在目录
* -e和!-e用来判断是否存在文件或目录
* -x和!-x用来判断文件是否可执行

Nginx全局变量
$args
$content_length
$content_type
$document_root
$document_uri
$host
$http_user_agent
$http_cookie
$limit_rate
$request_body_file
$request_method
$remote_addr
$remote_port
$remote_user
$request_filename
$request_uri
$query_string
$scheme
$server_protocol
$server_addr
$server_name
$server_port
$uri


摘录4:nginx重定向规则详细介绍(原创)

Nginx的重定向用到了Nginx的HttpRewriteModule,下面简单解释以下如何使用的方法:

rewrite命令
nginx的rewrite相当于apache的rewriterule(大多数情况下可以把原有apache的rewrite规则加上引号就可以直接使用),它可以用在server,location 和IF条件判断块中,命令格式如下:
rewrite 正则表达式 替换目标 flag标记
flag标记可以用以下几种格式:
last – 基本上都用这个Flag。
break – 中止Rewirte,不在继续匹配
redirect – 返回临时重定向的HTTP状态302
permanent – 返回永久重定向的HTTP状态301
例如下面这段设定nginx将某个目录下面的文件重定向到另一个目录,$2对应第二个括号(.*)中对应的字符串:
location /download/ {
rewrite ^(/download/.*)/m/(.*)\..*$ $1/nginx-rewrite/$2.gz break;
}

nginx重定向的IF条件判断
在server和location两种情况下可以使用nginx的IF条件判断,条件可以为以下几种:
正则表达式

如:
匹配判断
~  为区分大小写匹配; !~为区分大小写不匹配
 ~* 为不区分大小写匹配;!~为不区分大小写不匹配
例如下面设定nginx在用户使用ie的使用重定向到/nginx-ie目录下:
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /nginx-ie/$1 break;
}
文件和目录判断
  -f和!-f判断是否存在文件
 -d和!-d判断是否存在目录
 -e和!-e判断是否存在文件或目录
 -x和!-x判断文件是否可执行
例如下面设定nginx在文件和目录不存在的时候重定向:
if (!-e $request_filename) {
proxy_pass http://127.0.0.1;
}

return
返回http代码,例如设置nginx防盗链:
location ~* \.(gif|jpg|png|swf|flv)$ {
valid_referers none blocked www.jefflei.com www.leizhenfang.com;
if ($invalid_referer) {
return 404;
}
}

set
设置nginx变量


摘录5:NGINX 502错误排查

NGINX 502 Bad Gateway错误是FastCGI有问题,造成NGINX 502错误的可能性比较多。将网上找到的一些和502 Bad Gateway错误有关的问题和排查方法列一下,先从FastCGI配置入手:

1.查看FastCGI进程是否已经启动
NGINX 502错误的含义是sock、端口没被监听造成的。我们先检查fastcgi是否在运行

2.检查系统Fastcgi进程运行情况
除了第一种情况,fastcgi进程数不够用、php执行时间长、或者是php-cgi进程死掉也可能造成nginx的502错误
运行以下命令判断是否接近FastCGI进程,如果fastcgi进程数接近配置文件中设置的数值,表明worker进程数设置太少
netstat -anpo | grep "php-cgi" | wc -l

3.FastCGI执行时间过长
根据实际情况调高以下参数值
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;

4.头部太大
nginx和apache一样,有前端缓冲限制,可以调整缓冲参数
fastcgi_buffer_size 32k;
fastcgi_buffers 8 32k;
如果你使用的是nginx的负载均衡Proxying,调整
proxy_buffer_size  16k;
proxy_buffers      4 16k;
参见:http://www.ruby-forum.com/topic/169040

5.https转发配置错误
正确的配置方法
server_name www.mydomain.com;
location /myproj/repos {
set $fixed_destination $http_destination;
if ( $http_destination ~* ^https(.*)$ )
{
set $fixed_destination http$1;
}
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Destination $fixed_destination;
proxy_pass http://subversion_hosts;
}

参见:http://www.ruby-forum.com/topic/169040

当然,还要看你后端用的是哪种类型的FastCGI,我用过的有php-fpm,流量约为单台机器40万PV(动态页面), 现在基本上没有碰到502。

上一篇: 忘记UCenter创始人密码怎么办
下一篇: 中国八大域名注册商的优缺点[转]

访客评论

Gravatar
写的非常的好,有帮助,非常感谢
Post by peter on 2010-04-28, 11:24 PM #1

发表评论