AngularJS和处理404错误

时间:2013-07-08 04:44:58

标签: javascript angularjs flask http-status-code-404 angularjs-routing

使用AngularJS应用程序提供正确404的最佳方法是什么?

一点背景:我正在构建一个Angular应用并选择使用

$locationProvider.html5Mode(true);

因为我希望网址显得自然(与多页“传统”网络应用无法区分)。

在服务器端(一个简单的Python Flask应用程序),我有一个全能的处理程序,可以将所有内容重定向到角度应用程序:

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

现在,我正在试图弄清楚如何处理404错误。我见过的大多数Angular应用都会做到以下几点:

.otherwise({ redirectTo: '/' })

这意味着他们无法提供适当的404.

但是,我宁愿返回一个正确的404,带有404状态代码(主要用于搜索引擎优化目的)。

使用Angular处理404s的最佳方法是什么?我不应该担心它并坚持一个全能的?或者我应该删除全部服务器并在服务器端提供正确的404?

为了清晰起见而编辑

5 个答案:

答案 0 :(得分:32)

我认为你将Flask路线与Angular路线混淆。

404错误代码是HTTP协议的一部分。当服务器不知道请求的URL时,Web服务器将其用作对客户端的响应。因为你在Flask服务器中放置了一个全能型,所以你永远不会获得404,Flask会为你在地址栏中输入的任何URL调用你的视图功能。在我看来,当用户在地址栏中键入无效的URL时,你不应该有一个全能,只是让Flask回复404,这没有任何问题。 Flask甚至允许您在返回404代码时发送自定义页面,因此您可以使错误页面看起来与您网站的其余部分一样。

在Angular方面,实际上没有HTTP事务,因为应用程序内部的所有路由都发生在客户端,而服务器甚至不知道。这可能是您混淆的一部分,Angular链接完全在客户端处理,即使在html5mode中也没有向服务器发出任何请求,因此在此上下文中没有404错误的概念,因为没有服务器参与。将您发送到未知路由的Angular链接将属于otherwise子句。这里要做的正确的事情是要么显示错误消息(如果用户需要了解这个条件并且可以对此做些什么),要么忽略未知路由,就像redirectTo: '/'那样。

这似乎不是你的情况,但如果除了服务Angular应用程序之外,你的服务器还实现了Angular在运行时可以使用的API,那么如果Angular向它发出异步请求,那么Angular可以从Flask获得404使用无效网址的API。但如果发生这种情况,您不希望向用户显示404错误页面,因为该请求是应用程序内部的,而不是由用户直接触发。

我希望这有助于澄清情况!

答案 1 :(得分:17)

在玩了一下之后,以及与Miguel的一些讨论,我编写了一些不同的解决方案:

  1. 只需使用全能,不要担心正确的404。这可以使用服务器端代码(就像我原来的解决方案一样)设置,或者更好,在网络服务器上重写URL。
  2. 为您的角度应用预留网站的某个部分(例如/app)。对于本节,设置一个全能,不要担心正确的404。您的其他网页将作为常规网页投放,并且访问不以/app开头的任何无效网址将导致正确的404。
  3. 持续确保app.js中的所有路由都在您的服务器端代码中镜像(是的,非常烦人),您可以在这些路由中为您的角度应用提供服务。所有其他路线将为404。
  4. P.S。第二种选择是我个人的最爱。我已经尝试过了,效果很好。

答案 2 :(得分:2)

这是一个旧帖子,但我在寻找答案的过程中突然看到它。

将此添加到appRoutes.js的末尾并制作404.html视图。

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

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

答案 3 :(得分:0)

如果您没有为网站的真实网页提供可用的非JavaScript内容,我认为真正的http 404对于SEO目的而言将毫无用处。搜索索引器不太可能呈现您的角度站点以进行索引。

如果您担心SEO,则需要某种服务器端方式来呈现角度页面呈现的内容。如果您有,那么为无效网址添加404是最容易解决的问题。

答案 4 :(得分:-2)

这是处理错误并且效果很好的最佳方法

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'
        })

        ......

   };