重写 apache 2 的规则以与 angular js 一起使用
Posted
技术标签:
【中文标题】重写 apache 2 的规则以与 angular js 一起使用【英文标题】:rewrite rules for apache 2 to use with angular js 【发布时间】:2013-02-23 09:50:02 【问题描述】:显然,整个网络上有很多关于 mod 重写的讨论和答案。但是,我很难掌握它们。所以我想我会在这里问。
我要求重写规则来执行 Andy Joslin 在 cmets 中解释的内容:https://***.com/a/11100438
这是我当前位于 example.com 根目录的目录结构
应用/ app/index.html(Angular js 应用程序的“根”) api(这将是一个用于 'api' 的 symfony 2 应用程序。我将从 angular 向此处发送 ajax 请求。)我想将所有请求重定向到 app/index.html,但对 /api 的请求除外。
例如:
http://example.com/categories/electronics/ipod 实际上就像去http://example.com/app/index.html/categories/electronics/ipod
我希望 app/index.html 部分隐藏起来。
然后,对http://example.com/api 的请求会有一个例外,因为我需要向这些 url 路径发出 ajax 请求。
感谢所有帮助/指导。
【问题讨论】:
我认为这个问题不应该被关闭它是关于 angularjs 和 url-rewrite 两个主题都是相关的。 这被标记为“离题”是没有意义的。这不是题外话。 @casperOne,请打开这个备份。 【参考方案1】:这里有一些东西可以帮助你(把它放在你的 /.htaccess 文件中):
Options +FollowSymLinks
IndexIgnore */*
RewriteEngine on
# if a directory or a file exists, use it directly
RewriteCond %REQUEST_FILENAME -s [OR]
RewriteCond %REQUEST_FILENAME -l [OR]
RewriteCond %REQUEST_FILENAME -d
RewriteCond %REQUEST_URI !/api
# otherwise forward it to index.html
RewriteRule ^.*$ - [NC,L]
RewriteRule ^app/. /app/index.html [NC,L]
注意:对于较新的 Apache 版本,另请参阅下一个答案,它使用更简单的 FallbackResource
【讨论】:
谢谢,我会尽我所能。我现在正在研究一个关于重写的流行教程。我在想,我想做的不是仅仅因为文件存在就提供文件。问题是有人可以请求 Angular 调用的“部分”文件,它会为它提供服务,等等。我将把所有内容重定向到 app/index.html 然后我将明确跳过某些目录,例如 css/img / 这段代码几乎解决了我的问题......我不得不稍微改变一下应用程序规则,我在这个答案上留下了我的工作示例:***.com/a/15415902/54848 如果使用 localhost:xxxx,该文件保存在哪里?【参考方案2】:已接受此问题的答案已过时。您现在可以在 Apache 2.2.16+ 的 conf 文件中使用 FallbackResource 指令。
FallbackResource /app/index.html
如果您希望 FallbackResource 指令忽略“/api”路由:
<Directory /api>
FallbackResource disabled
</Directory>
【讨论】:
酷指令。但是,如何在忽略对“/api”的请求时使用它?这是我最初的问题。 如果您将其设置为专门忽略 /api 路由,则可以。我已经编辑了答案以反映这一点。【参考方案3】:这个答案的问题是您仍然需要 404 来表示未找到文件。根据人们构建前端应用程序的方式,人们让 css 或其他文件返回 404 是很常见的,尤其是当他们正在构建更大的动态应用程序或外包前端工作时。此外,角度路由通常与文件系统上的任何内容无关。如果您将其缩小到单个目录,上述方法可能会起作用。例如,我会经常为所有与文件系统布局 (/ajs/) 无关的角度路由使用一个公共前缀。如果可以的话
<Directory /ajs>
FallbackResource /app/index.html
</Directory>
然后它会更有意义,但这似乎对我不起作用。无论后端如何,使用公共前缀还可以使后端规则更加简单。例如,如果您不使用反向代理,您可以设置一个简单的服务器正向控制器。它使您的 apache 重写规则建模变得简单。例如:
RewriteEngine On
RewriteRule ^/ajs/(.+)$ /index.html
也就是说,我以前没有见过目录/回退方法,所以我有兴趣探索它,因为我需要的唯一重写是角前进。谢谢!
【讨论】:
【参考方案4】:这是对 Scott Ferguson 出色答案的细微改动和阐述。我发现使用<Location>
指令比使用<Directory>
更容易。 <Directory>
指令采用绝对路径名,在不同的机器上可能不同。
因此,假设您的 Angular 应用程序的 index.html
位于 Web 服务器文档根目录下的 my-app/index.html
中。并且您希望使用http://localhost/my-app
访问该应用程序。
首先确保您的基本href 是“/my-app/”。接下来,在您的 httpd.conf
文件中添加:
<Location "/my-app">
FallbackResource /my-app/index.html
</Location>
如果找不到/my-app/
下的任何资源,这将导致 Apache 加载 index.html。
如果您在同一路径下进行 API 调用,例如 /my-app/api
,那么您可能不应该对这些调用应用 FallbackResource
规则。所以添加:
<Location "/my-app/api">
FallbackResource disabled
</Location>
【讨论】:
【参考方案5】:从我的生产服务器:
<VirtualHost *:80>
ServerName XXX.com
DocumentRoot /home/www/XXX.com/www
# Local Tomcat server
<Location /api/>
ProxyPass http://localhost:8080/api/
ProxyPassReverse http://localhost:8080/api/
</Location>
RewriteEngine On
# If an existing asset or directory or API is requested go to it as it is
RewriteCond %DOCUMENT_ROOT%REQUEST_URI -f [OR]
RewriteCond %DOCUMENT_ROOT%REQUEST_URI -d [OR]
RewriteCond %REQUEST_URI /api
RewriteRule ^ - [L]
# If the requested resource doesn't exist (and is not API), use index.html
RewriteRule ^ /index.html
ErrorLog logs/XXX.com-error.log
CustomLog logs/XXX.com-access.log common
</VirtualHost>
请注意,“!”接受的答案中的“/api”之前是不正确的。
【讨论】:
以上是关于重写 apache 2 的规则以与 angular js 一起使用的主要内容,如果未能解决你的问题,请参考以下文章
如何在 .Htaccess 中禁用/不允许共享主机 RewriteLog 时,在 Apache 2 中模拟和测试 URL 重写规则?