AngularJS路由为不存在的路由隐藏404响应 [英] AngularJS routing hides 404 responses for nonexistent routes

查看:105
本文介绍了AngularJS路由为不存在的路由隐藏404响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到对不存在路径的GET请求不会返回404响应。相反,客户端获得200 Ok,AngularJS呈现主视图,并重写 / 的路径。在服务器日志中将对无意义URI的请求记录为成功。如果我理解正确,问题是由于AngularJS处理路由,服务器必须接受任何URI的GET请求,并始终通过为应用程序的客户端提供响应(200 Ok或304 Not Modified)。 / p>

例如,使用由 angular-fullstack Yeoman生成器,请求不存在的 / unicorn 如下所示:

  GET /独角兽200 31ms  -  3.29kb 
GET / partials / main 304 36ms
GET / api / awesomeThings 304 5ms

处理请求的Express路线如下所示:

  //服务器,最后一条路线:
app.get('*',controllers.index);

//控制器:
exports.index = function(req,res){
res.render('index');
};

index.jade 是根应用程序的整个客户端。



快速查看Github上其他AngularJS / Express项目的服务器端代码( AngularJS Express种子 AngularJS登录),我看到这是一种常见的模式。我想知道是否有更好的方法来处理不存在路径的请求,以便客户端获得真正的HTTP 404响应?

解决方案

角度文档包含有关路由的部分。此外,这个问题问题有一些与IIS有关但可以很容易地适应表达的信息。

  Html链接重写
当如果您使用HTML5历史记录API模式,则需要在不同浏览器中使用不同的链接,但您只需指定常规URL链接,例如:< a href =/ some?foo = bar> link< / a> ;

当用户点击此链接时,

在旧版浏览器中,网址更改为/index.html#!/some?foo=bar
In一个现代的浏览器,URL更改为/ some?foo = bar
如下所示,链接不会被重写;相反,浏览器将执行整页重新加载到原始链接。

包含目标元素
的链接示例:< a href =/ ext / link?a = btarget =_ self> link< / a>
转到不同域的绝对链接
示例:< a href =http://angularjs.org/> link< / a>
以/开头的链接,在定义基数时导致不同的基本路径
示例:< a href =/ not-my-base / link> link< / a>
在域的根目录中运行Angular时,可能是同一目录中的普通应用程序,否则路由处理程序将尝试处理所有URL,包括映射到静态文件的URL。

为了防止这种情况,您可以将应用的基本href设置为< base href =。>然后将链接前缀添加到应该使用的URL。现在,指向不受Angular路由的位置的链接不带前缀。并且不会被$ routeProvider中的其他规则拦截。

服务器端
使用此模式需要在服务器端重写URL,基本上你必须重写你的应用程序入口点的所有链接(例如index.html)


I have noticed that GET requests for nonexistent paths don't return a 404 response. Instead, the client gets a "200 Ok", AngularJS renders the main view, and rewrites the path to /. A request for a nonsense URI is logged as successful in the server logs. If I understand correctly, the problem is that since AngularJS handles routing, the server has to accept a GET request for any URI and always respond by serving the client side of the app ("200 Ok" or "304 Not Modified").

For example, using the project scaffolded by the angular-fullstack Yeoman generator, requesting a nonexistent /unicorn goes like this:

GET /unicorn 200 31ms - 3.29kb
GET /partials/main 304 36ms
GET /api/awesomeThings 304 5ms

The Express route that handles the request looks like this:

// server, last route:
app.get('*', controllers.index);

// controllers:
exports.index = function(req, res) {
  res.render('index');
};

and index.jade is the root of the whole client side of the app.

After a quick look at the server side code of other AngularJS / Express projects on Github (AngularJS Express seed, AngularJS login), I see that this is a common pattern. I am wondering if there is a better way to handle requests for nonexistent paths, so that the client gets a real HTTP 404 response?

解决方案

The angular documentation has a section about the routing. Also, this question and this question have some information that pertains to IIS but could easily be adapted to express.

Html link rewriting
When you use HTML5 history API mode, you will need different links in different browsers, but all you have to do is specify regular URL links, such as: <a href="/some?foo=bar">link</a>

When a user clicks on this link,

In a legacy browser, the URL changes to /index.html#!/some?foo=bar
In a modern browser, the URL changes to /some?foo=bar
In cases like the following, links are not rewritten; instead, the browser will perform a full page reload to the original link.

Links that contain target element
Example: <a href="/ext/link?a=b" target="_self">link</a>
Absolute links that go to a different domain
Example: <a href="http://angularjs.org/">link</a>
Links starting with '/' that lead to a different base path when base is defined
Example: <a href="/not-my-base/link">link</a>
When running Angular in the root of a domain, along side perhaps a normal application in the same directory, the "otherwise" route handler will try to handle all the URLs, including ones that map to static files.

To prevent this, you can set your base href for the app to <base href="."> and then prefix links to URLs that should be handled with .. Now, links to locations, which are not to be routed by Angular, are not prefixed with . and will not be intercepted by the otherwise rule in your $routeProvider.

Server side
Using this mode requires URL rewriting on server side, basically you have to rewrite all your links to entry point of your application (e.g. index.html)

这篇关于AngularJS路由为不存在的路由隐藏404响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆