特定 Angular 路由上的 Nginx 403 错误
Nginx 403 Error on Specific Angular Route
所以我有一个 angular 应用程序,它有几条我可以轻松到达的路线。
但是,/admin
使我不知所措,因为我收到了 403 错误。工作路线的示例,在 /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) 的漂亮 url 并且(除了 /admin
)能够刷新并重新 -通过 Angular.
正确加载该状态
但是,如果我将我的 app.config
管理状态更改为 url 的 /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/
.
您的逻辑路径似乎与您的 "physical" 路径冲突。
UiRouter 拦截客户端的请求。每次您尝试获取 "foo.bar/admin" 时,它都会检查路由 table 并显示 "uhm, this is registered as a logical path (client side), so it doesn't need to query the server"。
问题是,当你直接请求 "foo.bar/admin" 而不是导航到它时,nginx 是第一个收到请求的(因为 uiRouter 甚至不会被加载),并且因为你在服务器中使用相同的路径存储文件,而不是 returning index.html 文件,你的另一个
rules try_files $uri $uri/
具有优先权并尝试在您的服务器上找到它。但是当然,它找不到它,因为那里没有 'admin' 文件。我相信它不是 404,因为该路径实际上存在于服务器上,但它是一个目录,因此它不能 return 它,所以它会检测到 403。
一个可能的解决方案就是避免路径冲突,就像您将 'admin' 重命名为 'admins' 时所做的那样。由于 nginx 在服务器上找不到 'admins',它回退到 index.html.
其他解决方案是使用 gulp 或 grunt 之类的东西来压缩文件并避免有多个目录(因此路径冲突)。
最后,您可以重写一些规则以将 /admin 重定向到 index.html... 但我不会这样做。另外两个是更好的选择。
遗憾的是,我对 angular 没有太多经验,但我可以说,当您请求 url 时,例如 /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/
部分, 所以最后的 try_files
行是
try_files $uri /index.html;
所以我有一个 angular 应用程序,它有几条我可以轻松到达的路线。
但是,/admin
使我不知所措,因为我收到了 403 错误。工作路线的示例,在 /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) 的漂亮 url 并且(除了 /admin
)能够刷新并重新 -通过 Angular.
但是,如果我将我的 app.config
管理状态更改为 url 的 /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/
.
您的逻辑路径似乎与您的 "physical" 路径冲突。
UiRouter 拦截客户端的请求。每次您尝试获取 "foo.bar/admin" 时,它都会检查路由 table 并显示 "uhm, this is registered as a logical path (client side), so it doesn't need to query the server"。 问题是,当你直接请求 "foo.bar/admin" 而不是导航到它时,nginx 是第一个收到请求的(因为 uiRouter 甚至不会被加载),并且因为你在服务器中使用相同的路径存储文件,而不是 returning index.html 文件,你的另一个
rules try_files $uri $uri/
具有优先权并尝试在您的服务器上找到它。但是当然,它找不到它,因为那里没有 'admin' 文件。我相信它不是 404,因为该路径实际上存在于服务器上,但它是一个目录,因此它不能 return 它,所以它会检测到 403。
一个可能的解决方案就是避免路径冲突,就像您将 'admin' 重命名为 'admins' 时所做的那样。由于 nginx 在服务器上找不到 'admins',它回退到 index.html.
其他解决方案是使用 gulp 或 grunt 之类的东西来压缩文件并避免有多个目录(因此路径冲突)。
最后,您可以重写一些规则以将 /admin 重定向到 index.html... 但我不会这样做。另外两个是更好的选择。
遗憾的是,我对 angular 没有太多经验,但我可以说,当您请求 url 时,例如 /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/
部分, 所以最后的 try_files
行是
try_files $uri /index.html;