45

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

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

$locationProvider.html5Mode(true);

因为我希望 URL 看起来自然(并且与多页“传统”网络应用程序无法区分)。

在服务器端(一个简单的 Python Flask 应用程序),我有一个包罗万象的处理程序,它将所有内容重定向到 Angular 应用程序:

@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 状态码(主要用于 SEO 目的)。

使用 Angular 处理 404 的最佳方法是什么?我应该不担心它并坚持一个包罗万象的事情吗?或者我应该删除所有内容并在服务器端提供正确的 404?

为清楚起见进行了编辑

4

5 回答 5

34

我认为您将 Flask 路由与 Angular 路由混淆了。

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

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

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

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

于 2013-07-08T07:53:05.793 回答
18

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

  1. 只需使用包罗万象,不要担心正确的 404。这可以使用服务器端代码(就像我的原始解决方案一样)进行设置,或者更好的是,在您的 Web 服务器上重写 URL。
  2. 为您的 Angular 应用程序保留网站的某个部分(例如/app)。对于本节,设置一个包罗万象的内容,不要担心正确的 404。您的其他页面将作为常规页面提供,并且访问任何不以开头的无效 URL/app将导致正确的 404。
  3. 不断确保 app.js 中的所有路由都反映在您的服务器端代码中(是的,非常烦人),在那里您将让这些路由为您的 Angular 应用程序提供服务。所有其他路线将 404。

PS第二个选项是我个人最喜欢的。我已经试过了,效果很好。

于 2013-08-09T18:31:32.160 回答
2

这是一个旧线程,但我在寻找答案时遇到了它。

将此添加到 appRoutes.js 的末尾并创建一个 404.html 视图。

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

.otherwise({ redirectTo: '/404' })
于 2016-11-18T05:38:20.407 回答
0

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

如果您担心 SEO,您将需要某种服务器端方式来呈现您的 Angular 页面正在呈现的内容。如果有,为无效 URL 添加 404 是问题中最简单的部分。

于 2016-07-21T17:28:52.500 回答
-1

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

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

        ......

   };
于 2014-03-08T14:51:14.303 回答