backbone.js - Reescribiendo nginx para pushState-URL's




rewrite (5)

Lo logré así:

#set root and index
root /var/www/conferences/video/;
index  index.html;

#route all requests that don't serve a file through index.html
location / {
   if (!-e $request_filename){
      rewrite ^(.*)$ /index.html break;
   }
}

Estoy tratando de hacer que nginx funcione con mi pushState de URI basado en pushState que backbone.js administra para mí en una aplicación de Javascript.

Ahora mismo accediendo a los URI con un nivel, ej. example.com/users funciona bien, pero no con URI de dos niveles o más profundos, como example.com/users/all , que se menciona en la documentación de Backbone :

Por ejemplo, si tiene una ruta de / documents / 100, su servidor web debe poder servir esa página, si el navegador visita esa URL directamente

Por lo tanto, al estar lejos de conocer las opciones de reescritura de nginx, estoy seguro de que puedo hacer algo como rewrite ^ /index.html; para redirigir todo a mi index.html , pero perdiendo cualquier archivo estático eventual (imágenes, javascript y css) almacenado en el mismo servidor al que necesito poder acceder.

Entonces, ¿qué debo hacer con la configuración actual que se muestra a continuación para que esto funcione?

server {
    listen   80;
    server_name  example.com;

    location / {
        root   /var/www/example.com;
        try_files $uri /index.html;
    }

}

Esto es lo que hice con mi aplicación. Cada ruta que termine con un '/' (excepto la raíz propia) servirá index.html :

  location ~ ^/.+/$ {
    rewrite .* /index.html last;
  }

También puede prefijar su ruta:

Backbone.history.start({pushState: true, root: "/prefix/"})

y entonces :

  location ~ ^/prefix/ {
    rewrite .* /index.html last;
  }

O define una regla para cada caso.


Con las rutas de acceso del lado del cliente:

/
/foo
/foo/bar
/foo/bar/baz
/foo/bar/baz/123
/tacos
/tacos/123

Utilizar:

server {
    listen 80;
    server_name example.com;
    root /var/www/example.com;

    gzip_static on;

    location / {
      try_files $uri $uri/ /index.html;
    }

    # Attempt to load static files, if not found route to @rootfiles
    location ~ (.+)\.(html|json|txt|js|css|jpg|jpeg|gif|png|svg|ico|eot|otf|woff|woff2|ttf)$ {
      try_files $uri @rootfiles;
    }

    # Check for app route "directories" in the request uri and strip "directories"
    # from request, loading paths relative to root.
    location @rootfiles {
      rewrite ^/(?:foo/bar/baz|foo/bar|foo|tacos)/(.*) /$1 redirect;
    }
}

Mientras que la respuesta de @Adam-Waite funciona para la raíz y las rutas en el nivel raíz, usar si dentro del contexto de ubicación se considera un antipatrón, a menudo visto al convertir las directivas de estilo de Apache. Ver: http://wiki.nginx.org/IfIsEvil .

Las otras respuestas no cubren rutas con profundidad de directorio para mi caso de uso en una aplicación similar de React que usa react-router y HTML5 pushState habilitado. Cuando se carga o se actualiza una ruta dentro de un "directorio" como example.com/foo/bar/baz/213123 mi archivo index.html hará referencia al archivo js en una ruta relativa y se resolverá en example.com/foo/bar/baz/js/app.js lugar de example.com/js/app.js .

Para casos con profundidad de directorio más allá del primer nivel como /foo/bar/baz , tenga en cuenta el orden de los directorios declarados en la directiva @rootfiles: las rutas más largas posibles deben ir primero, seguidas por la siguiente ruta menos profunda /foo/bar y finalmente /foo .


Dado que puede haber solicitud de solicitud jajaja, los siguientes juicios para este caso,

server {
    listen 80;
    server_name example.com;
    root /var/www/example.com;

    # Any route containing a file extension (e.g. /devicesfile.js)
    location ~ ^.+\..+$ {
        try_files $uri =404;
    }

    # Any route that doesn't have a file extension (e.g. /devices)
    location / {
        try_files $uri /index.html;
    }

    # The location block above provides the shortest prefix, of length one, 
    # and so only if all other location blocks fail to provide a match, 
    # this block will be used.

    # Ajax api starts with /v1/ will be proxied
    location /v1/ {
        proxy_pass http://proxy;
    }
}

Tengo el mismo problema con mi servidor de desarrollo. Después de buscar en Internet, encontré esta discusión ( nginx, apache y error de administrador impar ) donde la solución es modificar la configuración del proxy de nginx.

La configuración de configuración para modificar es:

proxy_set_header            Host $host;

la solución es agregar el número de puerto:

proxy_set_header            Host $host:$server_port;

En mi ngnix + apache2 (con trabajador mpm) + django ahora todo funciona bien.





nginx backbone.js rewrite pushstate