15

我正在尝试将 /index.html 重写为 / 以用于 SEO 目的(愚蠢的搜索引擎将 index.html 与 / 混淆并惩罚重复的内容)——同时也是为了协调网络分析数据。

我已经尝试了在 stackoverflow、nginx 文档等上找到的所有解决方案,但都没有成功。我在想我必须有一些其他的配置问题或其他明显的痛苦。这是我的第一个 nginx 安装——用于 Apache 和 IIS!

这是我的 default.conf:

server {
    listen       80;
    server_name  web.local;
    #charset koi8-r;
    #access_log  /var/log/nginx/log/host.access.log  main;

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /var/www/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

这是我的 virtual.conf(注释掉的部分是我最近的尝试——当您尝试访问 www.domain.com/index.html 时,未注释它会给出 301 Moved Permanently 错误):

server {
    listen       80;
    server_name  www.domain.com;

    location / {
        root   /var/www/html/domain.com;
        index  index.html;
        #if ($request_uri = /index.html) {
        #    rewrite ^ http://www.domain.com permanent;
        #}
    }
}

server {
    listen 80;
    server_name domain.com;
    rewrite ^/(.*) http://www.domain.com/$1 permanent;
    }

cobaco 解决方案的 HTTP 响应标头:

URL:
http://www.domain.com
http/1.1 301 moved permanently
server: nginx/1.2.8
date: Thu, 16 May 2013 01:42:58 GMT
content-type: text/html
content-length: 184
connection: keep-alive
location: http://domain.com/

Redirecting URL:
http://domain.com/
http/1.1 301 moved permanently
server: nginx/1.2.8
date: Thu, 16 May 2013 01:42:58 GMT
content-type: text/html
content-length: 184
connection: keep-alive
location: http://www.domain.com/

我认为这行可能会导致问题:“location = /index.html {return 301 $scheme://domain.com/;}”所以我添加了 www。在“scheme://”之后——让我知道这是否是一件坏事!这导致了以下 HTTP 响应标头:

URL:
http://www.domain.com
http/1.1 301 moved permanently
server: nginx/1.2.8
date: Thu, 16 May 2013 01:42:58 GMT
content-type: text/html
content-length: 184
connection: keep-alive
location: http://www.domain.com/

Redirecting URL:
http://www.domain.com/
http/1.1 301 moved permanently
server: nginx/1.2.8
date: Thu, 16 May 2013 01:42:58 GMT
content-type: text/html
content-length: 184
connection: keep-alive
location: http://www.domain.com/

经过更多的修改,以下配置完成了我想要它做的事情,但由于 if 语句而不理想。有什么建议么?

server {
  server_name  www.domain.com;
  root /var/www/html/domain.com;
  index index.html;
  if ($request_uri = /index.html) {
      return 301 http://www.domain.com/;
  }
  #location = /index.html {
  #    return 301 $scheme://www.domain.com/;
  #}
}

server {
  listen 80;
  server_name domain.com;
  return 301 $scheme://www.domain.com$request_uri;
}
4

3 回答 3

11

你的最终解决方案完全没问题。

iflocation指令只有在块内时才是邪恶的。此外,您在块内只有一个return指令。if我看不出有什么问题。参考:http ://wiki.nginx.org/IfIsEvil

cobaco 解决方案中的无限重定向循环是因为

  index  index.html;

触发另一轮位置匹配。所以 nginxlocation = /index.html在重定向到http://www.domain.com/.

于 2013-05-16T12:14:07.840 回答
1

The following will do what you want:

server {
  server_name  www.domain.com;
  root /var/www/html/domain.com;
  index index.html;
  location = /index.html {return 301 $scheme://www.domain.com/;}
}

server {
  listen 80;
  server_name domain.com;
  return 301 $scheme://www.domain.com$request_uri;
}

To note:

  • use a location block instead of if when possible (because if inside a location is known to cause problems see http://wiki.nginx.org/IfIsEvil for the details)
  • use return not rewrite for 301's (as it's more efficient)
  • use the builtin variables instead of regex matching (as it's more efficient, see http://wiki.nginx.org/HttpCoreModule#Variables for a list of builtin variables)
  • root and index directives should normally always be at the main level of the server-block (else you need to repeat them for each sub-block)
于 2013-05-14T13:05:38.080 回答
-1

301 并不是真正的错误,它只是一个标头告诉浏览器它需要重定向到新的目的地,Web 浏览器会自动且静默地处理这些标头,但是如果您正在编写一些 curl 应用程序,那么您应该指示它尊重和处理这些标题。它是 301 因为你permanent在配置中写了 302 是temporary

当我尝试您的重写时,它对我有用,但是我在非重定向服务器中使用了 return 而不是 rewrite

location = /index.html {
    return 301 $scheme://$host;
}

如果您将重定向服务器也更改为使用 return 会更好

server {
    server_name domain.com;
    return 301 $scheme://www.domain.com$request_uri;
}

编辑:将 if 块更改为 location 块,就像@cobaco 建议的那样,我不知道为什么我错过了这样一个愚蠢的错误

于 2013-05-14T06:12:54.977 回答