Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

nginx /index.html to / rewrite

Tags:

nginx

rewrite

I am trying to rewrite /index.html to / for SEO purposes (stupid search engines which confuse index.html with / and penalize for duplicate content) -- also to reconcile web analytics data.

I've tried every solution I've found on stackoverflow, nginx documentation, etc and have had no success. I'm thinking I must have some other configuration issue or something else painfully obvious. This is my first nginx installation -- used to Apache and IIS!!

Here is my 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;
    #}

Here is my virtual.conf (commented out section was my most recent attempt -- when uncommented it gives a 301 Moved Permanently error when you attempt to access www.domain.com/index.html):

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;
    }

HTTP Response Headers for cobaco's solution:

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/

I figured that this line might be causing problems: "location = /index.html {return 301 $scheme://domain.com/;}" so I added www. after "scheme://" -- let me know if this is a bad thing to do! This resulted in the following HTTP Response Headers:

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/

After some more tinkering, the following configuration does what I want it to do but is not ideal due to the if statement. Any suggestions?

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;
}
like image 320
auralsun Avatar asked May 14 '13 04:05

auralsun


People also ask

What does rewrite to nginx?

Nginx rewrite rules can be defined within your Nginx configuration file in order to change at least part or all of a URL. Usually, this is done for one of two purposes. First, if a URL has changed, using a rewrite rule will let the client know that the resource requested is in a different location.

What is return 301 in nginx?

Permanent redirects such as NGINX 301 Redirect simply makes the browser forget the old address entirely and prevents it from attempting to access that address anymore. These redirects are very useful if your content has been permanently moved to a new location, like when you change domain names or servers.


1 Answers

You final solution is totally fine.

if directive is evil ONLY IF it is inside a location block. Also you only have a return directive inside the if block. I don't see anything wrong with that. reference: http://wiki.nginx.org/IfIsEvil

The infinite redirect loop in cobaco's solution is because

  index  index.html;

triggers another round of location match. So nginx will be trapped into the location = /index.html again after it's redirected to http://www.domain.com/.

like image 199
Chuan Ma Avatar answered Oct 16 '22 05:10

Chuan Ma