link example javascript angularjs flask http-status-code-404 angularjs-routing

javascript - example - AngularJS y manejo de errores 404



ng-href angular 5 (5)

¿Cuál es la mejor manera de servir los 404 adecuados con una aplicación AngularJS?

Un poco de historia: estoy construyendo una aplicación Angular y he optado por usar

$locationProvider.html5Mode(true);

porque quiero que las URL parezcan naturales (e indistinguibles de una aplicación web "tradicional" de varias páginas).

En el lado del servidor (una simple aplicación Python Flask), tengo un controlador catch-all que redirige todo a la aplicación angular:

@app.route(''/'', defaults={''path'': ''''}) @app.route(''/<path>'') def index(path): return make_response(open(''Ang/templates/index.html'').read())

Ahora, estoy tratando de averiguar qué hacer con los errores 404. La mayoría de las aplicaciones de Angular que he visto hacen lo siguiente:

.otherwise({ redirectTo: ''/'' })

lo que significa que no hay forma de que puedan servir un 404 apropiado.

Sin embargo, preferiría devolver un código 404 apropiado, con un código de estado 404 (principalmente para fines de SEO).

¿Cuál es la mejor manera de manejar 404s con Angular? ¿No debería preocuparme por eso y quedarme con un catch-all? ¿O debería eliminar el catch-all y servir los 404 adecuados en el lado del servidor?

editado para mayor claridad


Creo que estás confundiendo rutas de Flask con rutas Angulares.

El código de error 404 es parte del protocolo HTTP. Un servidor web lo usa como respuesta a un cliente cuando el servidor no conoce la URL solicitada. Debido a que pone un catch-all en su servidor Flask nunca obtendrá un 404, Flask invocará su función de vista para cualquier URL que escriba en la barra de direcciones. En mi opinión, no deberías tener un catch-all y simplemente dejar que Flask responda con 404 cuando el usuario escribe una URL no válida en la barra de direcciones, no hay nada de malo en eso. Flask incluso le permite enviar una página personalizada cuando se devuelve un código 404, por lo que puede hacer que la página de error se parezca al resto de su sitio.

En el lado angular, en realidad no existe una transacción HTTP porque todo el enrutamiento interno de la aplicación ocurre en el cliente sin que el servidor lo sepa. Esto puede ser parte de su confusión. Los enlaces angulares se manejan completamente en el cliente sin ninguna solicitud hecha al servidor, incluso en html5mode, por lo que no existe un concepto de error 404 en este contexto, simplemente porque no hay participación del servidor. Un enlace angular que le envía a una ruta desconocida simplemente caerá en la cláusula de lo otherwise . Lo apropiado para hacer aquí es mostrar un mensaje de error (si el usuario necesita saber sobre esta condición y puede hacer algo al respecto) o simplemente ignorar la ruta desconocida, como lo hace el redirectTo: ''/'' .

Este no parece ser tu caso, pero si además de servir a la aplicación Angular tu servidor implementó una API que Angular puede usar mientras se ejecuta, Angular podría obtener un 404 de Flask si hiciera una solicitud asíncrona a esta API usando un URL invalida. Pero, si eso ocurriera, no le gustaría mostrar una página de error 404, ya que la solicitud era interna para la aplicación y el usuario no la activaba directamente.

¡Espero que esto ayude a aclarar la situación!


Creo que un verdadero http 404 va a ser bastante inútil "para fines de SEO" si no está sirviendo contenido que no es de JavaScript utilizable para las páginas reales de su sitio. Es improbable que un indexador de búsqueda pueda representar su sitio angular para la indexación.

Si está preocupado por SEO, necesitará algún tipo de servidor para renderizar el contenido que están renderizando sus páginas angulares. Si tiene eso, agregar 404 para URL no válidas es la parte más fácil del problema.


Después de jugar un poco, así como algunas discusiones con Miguel, compilé algunas soluciones diferentes:

  1. Solo usa un catch-all y no te preocupes por los 404 apropiados. Esto se puede configurar con un código del lado del servidor (como en mi solución original), o mejor, con la reescritura de URL en su servidor web.
  2. Reserve una sección determinada de su sitio para su aplicación angular (como /app ). Para esta sección, configure un catch-all y no se preocupe por los 404 adecuados. Sus otras páginas se publicarán como páginas regulares y visitar cualquier URL inválida que no comience con /app dará como resultado 404 apropiado.
  3. Continuamente asegúrese de que todas sus rutas en app.js estén reflejadas en su código del lado del servidor (sí, bastante molesto), donde tendrá esas rutas que le servirán a su aplicación angular. Todas las demás rutas serán 404.

PD: la segunda opción es mi favorito personal. Lo probé y funciona bastante bien.


Este es un hilo viejo, pero lo recorro mientras busco la respuesta.

Agregue esto al final de su appRoutes.js y haga una vista 404.html.

.when(''/404'', { templateUrl: ''views/404.html'', controller: ''MainController'' }) .otherwise({ redirectTo: ''/404'' })


Esta es la mejor manera de manejar el error y funciona bien

function ($routeProvider, $locationProvider, $httpProvider) { var interceptor = [ ''$rootScope'', ''$q'', function (scope, $q) { function success(response) { return response; } function error(response) { var status = response.status; if (status == 401) { var deferred = $q.defer(); var req = { config: response.config, deferred: deferred }; window.location = "/"; } if (status == 404) { var deferred = $q.defer(); var req = { config: response.config, deferred: deferred }; window.location = "#/404"; } // otherwise //return $q.reject(response); window.location = "#/500"; } return function (promise) { return promise.then(success, error); }; } ]; $httpProvider.responseInterceptors.push(interceptor); }); // routes app.config(function($routeProvider, $locationProvider) { $routeProvider .when(''/404'', { templateUrl: ''/app/html/inserts/error404.html'', controller: ''RouteCtrl'' }) .when(''/500'', { templateUrl: ''/app/html/inserts/error404.html'', controller: ''RouteCtrl'' }) ...... };