AngularJS和处理404错误
用AngularJS应用程序提供正确404的最佳方式是什么?AngularJS和处理404错误
一点背景:我要建一个角度应用程序,并选择使用
$locationProvider.html5Mode(true);
,因为我想要的网址出现自然(和无法区分多页的“传统”的Web应用程序)。
在服务器端(一个简单的Python应用程序瓶),我有一个重定向一切角应用一个包罗万象的处理程序:
@app.route('/', defaults={'path': ''})
@app.route('/<path>')
def index(path):
return make_response(open('Ang/templates/index.html').read())
现在,我试图找出该怎么做404错误。大多数我见过做以下的角的应用程序:
.otherwise({ redirectTo: '/' })
这意味着,有没有办法,他们可以成为一个适当的404
不过,我宁愿回到正确的404,与404状态代码(主要用于SEO目的)。
用Angular处理404s的最佳方式是什么?我不应该担心它,并坚持一个全面的?或者我应该删除捕获所有并在服务器端提供正确的404?
编辑为清楚起见
玩弄了一下,以及与米格尔一些讨论后,我整理了几个不同的解决方案:
- 只需使用一个包罗万象的,不要担心适当的404的。这可以通过服务器端代码(如我的原始解决方案)来设置,或者更好,在您的Web服务器上重新写入URL。
- 为您的角度应用保留您网站的某个部分(如
/app
)。对于本节,设置一个全面的,不要担心适当的404。您的其他页面将作为常规页面提供,并访问任何不以/app
开头的无效网址将导致404错误。 - 连续确保app.js中的所有路由都在您的服务器端镜像 - (是的,非常讨厌),你将有这些路线提供你的角度应用程序。所有其他路线将为404.
P.S.第二个选项是我个人的最爱。我已经试过了,它工作得很好。
我正遇到类似的问题,使用angular/node.js堆栈。我有一条使用特定ID进行数据查找的路线。对于一个好的URL,这可以正常工作。对于一个不好的网址,我只是用一个看起来破损的网页结束。这些网址看起来像:/ details/goodID vs. details/badID(我也注意到某些机器人喜欢尝试/ details/details/goodID,这也是一个糟糕的路线:/)。解决方案#2并没有真正处理这种情况,如果可能的话,我想避免#3。你遇到过其他想法吗?是否有404-ish的方式来报告错误客户端? – user3233032
@Ryan - 关于#3,需要通过browserify具有所有定义的路由模块并不是那么糟糕吗?无论如何,我就是这么做的。 – aaaaaa
@瑞恩原谅我,但没有这个服务器通话否定客户端SPA的全部点?我们称SPA为一次,然后通过Ajax使用Api。如果你必须去你的服务器的每个端点,那么为什么不简单地使用客户端/服务器模型? –
我想你混淆了瓶路线与角路线。
404错误代码是HTTP协议的一部分。当服务器不知道请求的URL时,Web服务器将其用作对客户端的响应。因为你在Flask服务器中加入了一个全新的东西,你永远不会得到一个404,Flask将为你在地址栏中输入的任何URL调用你的view功能。在我看来,你不应该有一个全面的,并让Flask用404响应,当用户在地址栏中键入一个无效的URL时,没有什么不对。 Flask甚至允许您在返回404代码时发送自定义页面,因此您可以使错误页面看起来像您网站的其余部分。
在Angular方面,确实没有HTTP事务,因为应用程序内部的所有路由发生在客户端,而服务器甚至不知道。这可能是你混淆的一部分,Angular链接完全在客户端处理,即使在html5mode中也没有向服务器发出任何请求,所以在这种情况下没有404错误的概念,仅仅是因为没有服务器参与。发送给未知路线的角度链接将落入otherwise
条款。这里要做的正确事情是显示错误消息(如果用户需要了解这种情况并可以做些什么),或者忽略未知路由,如redirectTo: '/'
所做的那样。
这似乎不是你的情况,但如果除了服务Angular应用程序之外,你的服务器还实现了一个Angular可以在运行时使用的API,那么Angular可以从Flask得到一个404,如果它向一个异步请求此API使用无效的网址。但是如果发生这种情况,您不希望向用户显示404错误页面,因为请求是应用程序内部的,并且不是由用户直接触发的。
我希望这有助于澄清情况!
我将删除catch-all,因为我希望能够提供适当的404错误(对于SEO等)。但是,现在我必须保留Flask传递给Angular的路由列表。这意味着,无论何时添加新路线,我都需要将其添加到我的app.js和我的controllers.py中。但说实话,我只想说一点事实。我怎么能更新一个位置的路线,并让它们在JS和Python代码中自动反映?我正在考虑用这些路由创建一个JSON文件(python会导入这些路由并在JSON文件被触摸时生成一个新的app.js)。 – Ryan
你仍然困惑着服务器和客户端。您的Flask应用程序只有一个路径,''/“'将Angular应用程序提供给客户端。而已。 Angular应用程序可以根据需要定义多条路线,但这些是客户端,Flask服务器不涉及这些路线。事实上,通过如此简单的设置,我不清楚为什么你需要服务器上的Flask,看起来你只是为Angular应用程序提供静态文件。 – Miguel
@Miguel我不会混淆他们。考虑一下:我在角度路由中使用了“/”和“/ about”的角度应用。我也启用了html5Mode。这意味着,如果用户转到“/”,则会向服务器发送请求,然后角度应用程序将启动。当用户导航到“/ about”时,请求将不会发送到服务器,因为角度应用程序现在正在处理它。但是,如果用户刷新页面,“/ about”将被发送到服务器。这意味着,需要在服务器上有一个“/ about”端点将请求传递到角度。 – Ryan
这里是处理错误的最好方式和工作很好
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'
})
......
};
我没有downvote - 但我知道SO更喜欢不严格代码的答案。只是一个建议,因为我很感谢大多数花时间回答他人问题的人。 – aaaaaa
它没有解决问题... –
我认为,一个真正的HTTP 404将是相当无用的“搜索引擎优化的目的,”如果你没有服务可用非-javascript内容为您的网站的真实网页。搜索索引器不太可能能够呈现您的角度网站进行索引。
如果您担心搜索引擎优化,您需要某种服务器端的方式来渲染角色页面呈现的内容。如果你有这个问题,为无效URL添加404s是问题中最容易的部分。
这是一个古老的线程,但我在搜索答案时找到它。
将此添加到appRoutes.js的最后并创建一个404.html视图。
.when('/404', {
templateUrl: 'views/404.html',
controller: 'MainController'
})
.otherwise({ redirectTo: '/404' })
要在404你可以提到你的使用情况怎样做 –
当一个访问/ ASDF,应该采取一个404页:“对不起,你要访问的页面不存在” 。应该返回404状态码。 – Ryan
你可以注册一个响应拦截器,并检查拦截器中的状态代码,你可以在http状态代码中找到404,你可以使用$ location.path('path')重定向到任何路径。 –