特定角度路径上的Nginx 403错误

时间:2015-02-06 06:20:17

标签: angularjs nginx url-rewriting vagrant

所以我有一个角度应用程序,有一些我可以很容易到达的路线。

然而,当我收到403错误时,/admin躲过了我。工作路线的一个例子,在/articles设置完全相同的方式加载就好了。

这是我的应用配置:

    app.config(['$stateProvider', '$locationProvider', '$urlRouterProvider',
    function($stateProvider, $locationProvider, $urlRouterProvider) {
        $stateProvider.
            ...
            state('articles', {
                url: '/articles',
                templateUrl: 'components/articles/templates/articles.tmpl.html',
                controller: 'ArticleController'
            }).
            state('articles/:id', {
                url: '/articles/:id',
                templateUrl: 'components/articles/templates/single-article.tmpl.html',
                controller: 'ArticleController'
            }).
            state('admin', {
                url: '/admin',
                templateUrl: 'admin/templates/admin.tmpl.html',
                controller: 'AdminController'
            }).
            state('admin.create', {
                url: '/create',
                templateUrl: 'admin/create/templates/create.tmpl.html',
                controller: 'AdminCreateController'
            }).
            ...
        $urlRouterProvider.otherwise('/');
        $locationProvider.html5Mode(true);
    }
]);

我知道罪魁祸首是Nginx 我知道它是用html5Mode触发的;所以我检查了我是如何重新路由到索引页面,它看起来很好(并且在网站上正常工作),这是我的nginx网站 - 可用conf:

server {

   listen 80;
   server_name app.local.dev;
   root "/vagrant/app";
   index index.html;
   location / {
       try_files $uri $uri/ /index.html;

   }

}

以下是Nginx的错误日志示例:

2015/02/06 06:14:23 [error] 3361#0: *20 directory index of "/vagrant/app/admin/" is forbidden, client: 192.168.99.1,

我的文件结构似乎没有任何权限(/admin文件所在的根文件夹:

-rw-r--r-- 1 vagrant vagrant  229 Feb  2 20:33 AdminController.js
-rw-rw-r-- 1 vagrant vagrant   90 Feb  2 05:18 AdminModule.js
drwxr-xr-x 1 vagrant vagrant  204 Feb  3 02:55 create
-rw-r--r-- 1 vagrant vagrant 6148 Feb  2 16:08 .DS_Store
drwxr-xr-x 1 vagrant vagrant  170 Feb  3 05:12 edit
drwxr-xr-x 1 vagrant vagrant  102 Feb  2 20:33 templates

/admin模板文件:

-rw-r--r-- 1 vagrant vagrant 151 Feb  2 20:33 admin.tmpl.html

/articles个文件所在的根文件夹:

-rw-r--r-- 1 vagrant vagrant 715 Feb  5 03:47 ArticleController.js
-rw-r--r-- 1 vagrant vagrant  94 Dec  3 18:29 ArticleModule.js
drwxr-xr-x 1 vagrant vagrant 136 Feb  6 04:19 templates

/articles模板文件:

-rw-r--r-- 1 vagrant vagrant 526 Feb  6 04:19 articles.tmpl.html
-rw-r--r-- 1 vagrant vagrant 453 Feb  5 22:35 single-article.tmpl.html

所以事情正在重新路由和正确写入。我可以点击我的主域名,在没有哈希的情况下获取我的主页并点击并保持一个不包含哈希值的漂亮网址(html5Mode)和(除/admin之外)能够点击刷新并正确重新加载该状态通过Angular。

但是,如果我将app.config管理员状态更改为/admins的网址,则会神奇地工作,重新加载会正确刷新/admins告诉我正确的观点。

state('admin', {
    url: '/admins', // works as expected and loads what was my /admin view with correct refreshing in Nginx
    templateUrl: 'admin/templates/admin.tmpl.html',
    controller: 'AdminController'
}).

那么在Nginx中是否存在某种奇怪的保留URL?我正在使用Vagrant并且特别关闭了sendfile,因为许多报告奇怪的缓存。我的nginx.conf设置错了吗?我觉得我的URL重写工作正常,因为它在网站上的其他地方工作。有效/articles的路由和不/admin的路由之间的唯一区别是/admin内部有嵌套状态,例如。 /admin/create/pages/

2 个答案:

答案 0 :(得分:2)

似乎你的逻辑路径与你的"物理"冲突?路径。

UiRouter拦截客户端上的请求。每次你试图得到" foo.bar/admin"它检查路由表并说“呃,这是注册为逻辑路径(客户端),所以它不需要查询服务器"。 问题是,当你直接请求" foo.bar/admin"而不是导航到它,nginx是第一个获取请求(因为uiRouter甚至无法加载),并且因为你在服务器中使用相同的路径来存储文件,而是返回index.html文件,你的另一个

  

规则try_files $ uri $ uri /

具有优先权并尝试在您的服务器上找到它。但是,当然,它没有找到它,因为没有“管理员”。归档那里。我认为它不是404,因为路径实际上存在于服务器上,但是它是一个目录,因此它不能返回它,所以它反而是403。

一种可能的解决方案就是避免路径冲突,就像重命名' admin'到管理员'。由于nginx没有找到管理员'在服务器上,它回退到index.html。

其他解决方案是使用gulp或grunt之类的东西来压缩文件并避免使用多个目录(因此会发生路径冲突)。

最后,你可以重写一些规则,以便将/ admin重定向到index.html ......但我不会这样做。另外两个是更好的选择。

答案 1 :(得分:1)

可悲的是,我没有太多使用角度的经验,但我可以说当你请求像/admin这样的网址时,nginx会检查你在try_files中指定的规则,这些规则是

$uri # check if there's a file called admin

当然你没有,所以它进入下一步

$uri/ #check if there's a directory called admin

它已被发现,因为你只提供了一个目录,所以它从

检查索引
index index.html;

所以nginx尝试查找/admin/index.html并假设它不存在,那么nginx会回到最后一个目录列表,但是因为你没有autoindex on那么它由于不允许使用目录索引,因此会回退到403错误。

如果您想跳过此步骤并提供index.html我认为它有一些与angular相关的代码,那么我建议的解决方案是完全删除$uri/部分,所以最后{{} 1}}行将是

try_files