Nginx绑定域名并配置www域名301转向

最近正好用到,在网上找了些资料,然后记录这里,算是备忘吧。对于Apache的.htaccess和ASP/PHP脚本定向的方法可以参考《主机域名www的自适应301重定向方法》

比如说我们有域名example.com,然后配置我们的Nginx服务器,希望绑定两个域名不带www的example.com以及www.example.com。绑定域名可以在你的Nginx配置文件的server {}节做下述配置。

  server {
    listen 80;
    server_name example.com www.example.com;
  }

这样配置后example.com和www.example.com都指向我们的服务器了,虽然这样没有什么,但是这对于搜索引擎是不友好的,不利于网站的SEO,所以我们需要利用301重定向一个域名到另一个域名上。

在Nginx的server节中引入$host变量,这个指代当前访客访问主机时使用的主机名(域名)。接下来我们可以利用if条件语句配合rewrite permanent方式做301定向了。

继续阅读

主机域名www的自适应301重定向方法

一般来说Web网站都是喜欢带www的,但是我觉得我的网站带www前缀有些略显不雅,所以我决定把www转向到不带www的域名上来,通常情况下使用301重定向

以前自己用ASP写过个转向的代码片段,供大家参考:

1
2
3
4
5
6
7
8
9
10
11
12
<%
Dim g_ReqServer
g_ReqServer = Request.ServerVariables("SERVER_NAME")
If InStr(1, g_ReqServer, "www.", 1)<>0 Then
    Response.Status="301 Moved Permanently" 
    Response.AddHeader "Location", "http://" &_
        Replace(LCase(g_ReqServer), "www.", "") &_
             Request.ServerVariables("PATH_INFO") & "?" &_
                    Request.QueryString()
    Response.End
End If
%>

这里解释下,首先Request.ServerVariables(“SERVER_NAME”)获取访问所使用的主机域名,然后通过InStr判断是不是包含www.,如果包含则返回301状态。紧接着拼接出新的网址,新的网址必定由http:// + 去掉www.的主机域名(这里调用Replace函数替换) + 所请求文件的路径信息PATH_INFO + ‘?’ + 所请求的字符串,之所以称为“自适应”是因为对于任何的URL,都只是单纯的去掉www.,原路径不变,所以问号和请求字符串就尤显重要了,如果省掉就可能导致查询字符串的丢失。

后来初学PHP,也照样子写过一段代码,如下:

1
2
3
4
5
6
7
8
9
<?php
$server_name = $_SERVER['SERVER_NAME'];
if(!stristr($server_name, 'www.')) {
 $pathinfo = parse_url($_SERVER['REQUEST_URI']);
 header("HTTP/1.1 301 Moved Permanently");
 header("Location: http://www." . $server_name . 
    $_SERVER['PHP_SELF']."?".$pathinfo['query']);
}
?>

基本原理是一样的,只不过要获得?后面的一大串查询字符串需要调用parse_url。

值得注意的是上述两段代码片段必须加在访问的页面代码顶端,也就是在任何Response或者echo输出之前,否则就失效了。

后来通过网上查询获得了个更好的方法,那就是.htaccess,在.htaccess的 里面添加下面的代码:

1
2
3
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.wangye\.org$
RewriteRule ^(.*)$   http://wangye.org/$1 [L,R=301]

初学.htaccess,感觉有点正则表达式的味道,首先匹配主机域名,如果是www.wangye.org就进行R=301的重定向。

2011年3月10日更新

Aaron Saray的博客上看到了个比较好的写法,包含了两种情况,分别是有带www的转向不带www的和不带www的转向带www,特别记录下来。

1
2
3
4
5
6
7
8
9
10
11
12
RewriteEngine On
RewriteBase /
 
#require WWW
RewriteCond %{HTTP_HOST} !^www\.(.+)$ [NC]
RewriteRule ^(.*)$ http://www.%1/$1 [R=301,L] 
 
#OR
 
#do not require www
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

2011年7月3日更新

根据未来往事所反映的关于PHP代码实现跳转,在处理URL重写(URL Rewrite)的情况下会丢失重写,回到原始带查询参数的链接地址,为此我将相关代码修改如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
// 定义你自己的URL路由表
// 比如下面的路由表将会把
// read.php?paramA=1&paramB=2&paramC=3
// 变成
// /post/1/2/3/
$router = array(
  'read.php'=>'/post/'
);
$server_name = $_SERVER['SERVER_NAME'];
if(!stristr($server_name, 'www.')) {
  $fn = explode('/', strtolower($_SERVER['PHP_SELF']));
  if (array_key_exists($fn[0], $router)) {
    $path = $router[$fn[0]] .
      implode('/',
        array_filter($_REQUEST,
           create_function('$v','return !empty($v);')));
  } else {
    $pathinfo = parse_url($_SERVER['REQUEST_URI']);
    $path = $_SERVER['PHP_SELF']."?".$pathinfo['query'];
  }
  header("HTTP/1.1 301 Moved Permanently");
  header("Location: http://www." . $server_name . $path);
}
?>

总结最后,还是建议大家在条件允许的情况下尝试采用301的DNS转向,目前有些DNS服务商已经免费提供这项功能。

  1. 301重定向 : 301代表永久性转移(Permanently Moved),301重定向是网页更改地址后对搜索引擎友好的最好方法,只要不是暂时搬移的情况,都建议使用301来做转址。[更多]
  2. .htaccess : Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过.htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。 [更多]