htaccess重定向到Angular路由


73

我有一些路线的角度应用程序,例如:

site.com/
site.com/page
site.com/page/4

使用angular的html5路由模式,当您从应用程序内单击指向链接的链接时,这些链接可以正确解析,但是当您进行硬刷新时,这些链接当然是404错误。为了解决这个问题,我尝试实现基本的htaccess重写。

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_METHOD} !OPTIONS
RewriteRule ^(.*)$ index.html [L]

这适用于角度请求,但是当我尝试在我的域内加载脚本或进行ajax调用时,例如:

<script src="/app/programs/script.js"></script>

该脚本不会加载-它的请求被重定向,并且它尝试加载index.html页,因为.htaccess认为它应该重新路由该请求-不知道此文件确实存在,因此应该加载该文件而不是重定向。

只有在没有实际文件可以解析的情况下,htaccess有什么方法可以使htaccess将请求重定向到index.html(带有视图参数)吗?


/app/programs/script.js有效文件吗?
anubhava 2014年

是的,如果没有我当前的.htaccess文件(如出现问题),此文件将正确解析。
2014年

这个技巧也适用于Angular 2。
Ashish Doneriya

Answers:


149

使用如下代码段:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]

RewriteRule ^(.*) /index.html [NC,L]

如果有的话,这将跳至实际资源,index.html对于所有AngularJS路由,这将跳至实际资源。


1
这几乎是完美的-尽管我不确定原因,但似乎无法处理带有参数的路由,例如site.com/page/4。
卢卡斯·彭尼2014年

1
事实证明,此方法工作得很好-我只有一些文件引用,但没有前导斜杠(/),因此试图在带有参数的路由中相对地进行解析。
Lucas Penney 2014年

2
@rajasaur非常感谢您-这就是为什么我喜欢stackoverflow。帮助我迅速解决了我认为整夜都想弄清楚的事情。
杰米2015年

2
您将htaccess文件放在哪里以及如何放置?
JohnAndrews

1
嗨,我有http://www.domain.com/dashboard。所以/dashboard只有我要打开角度项目的URL 。请帮助我如何写.htaccess同样的。实际上,我有2个不同的角度项目。第1个将在渲染http://www.domain.com,第2个应在渲染http://www.domain.com/dashboard
阿尼尔·库马尔·潘迪

20

如果应用程序请求directive模板文件,但文件丢失,则存在问题。在某些情况下,它导致应用请求了多个脚本文件index.html

如果文件不存在,我们应该发送404响应而不是index.html文件。所以我添加了简单的正则表达式模式来识别丢失的文件请求。

RewriteEngine On
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]

# If the requested pattern is file and file doesn't exist, send 404
RewriteCond %{REQUEST_URI} ^(\/[a-z_\-\s0-9\.]+)+\.[a-zA-Z]{2,4}$
RewriteRule ^ - [L,R=404]

# otherwise use history router
RewriteRule ^ /index.html

如果文件不存在,那么是否RewriteRule ^ - [L,R=404]可以使用RewriteRule ^ /index.html或重定向到index.html RewriteRule ^ - [L,R=/index.html]?我在appserver环境中,路径中断很多。不习惯.htaccess中的此类更改,但也只想将404重定向到index.html。
加里

是的,您可以跳过404部分,但这有什么意义。此.htaccess方法适用于缺少角度指令的资产/模板文件,而不是缺少路径。如果要处理缺少的路径,则应配置路由器提供程序本身,或者可以使用路由器事件。
端口115(2016年

我不需要.htaccess的404句柄。我想用index.html角度文件来处理所有这些问题
Gary

+1给出%{DOCUMENT_ROOT}在RewriteCond中使用的唯一答案,当您在VirtualHost中时,这是必需的-否则条件永远不会成立!
not2savvy

6

一个穷人的解决方案(不使用mod_rewrite):

ErrorDocument 404 /index.html

5

就我而言,我创建如下的.htaccess文件

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]

RewriteRule ^(.*) ./index.html [NC,L]

刚刚添加 。/index.html之前,然后将该文件添加到我的域中(例如https://example.com/subfolder),效果很好


3

查看此链接:https : //stackoverflow.com/a/49455101/5899936.htaccess在根文件夹中 创建文件,并将其放在.htaccess

 <IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</IfModule>

谢谢它为我工作。如果它是子目录,则添加RewriteBase /SubDir而不是RewriteBase /
sree

1

如果您需要,我将提供另一个详细的htaccess文件:

  • 考虑一下baseUrl和默认索引文件
  • 删除要管理的前斜杠:params

这是我的htaccess,非常接近,但更具体:

DirectoryIndex index.html
RewriteEngine on
RewriteBase /subDir
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^(.*) index.html [NC,L]

0

就我而言,我们需要更多的功能覆盖范围.htaccess配置,例如:

  • 强制使用HTTPS协议(在下面进行注释)。
  • Authorization标题转换为HTTP_AUTHORIZATION环境变量。
  • 跨域资源共享(CORS)。
  • 并禁用了特定格式的缓存(以及注释)。

# If mod_rewrite is not present.
<IfModule !mod_rewrite.c>
  FallbackResource /index.html
</IfModule>

<IfModule mod_rewrite.c>
  RewriteEngine On
  # Prefix for all rewritten routes ("index.html" gets "/index.html").
  RewriteBase /

  # Redirects to HTTPS protocol (once uncommented).
  #
#  RewriteCond %{HTTPS} !on
#  RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L]

  # Make sure Authorization HTTP header is available.
  RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

  # Allows access to existing files or dirs.
  RewriteCond %{REQUEST_FILENAME} -s [OR]
  RewriteCond %{REQUEST_FILENAME} -l [OR]
  RewriteCond %{REQUEST_FILENAME} -d
  RewriteRule ^.*$ - [NC,L]

  # Prevents treating the main-script as a route.
  RewriteRule ^index\.html$ - [L]
  # Redirect anything else to main-script
  RewriteRule ^(.*) index.html [NC,L]
</IfModule>

# Enable Cross-Origin Resource Sharing (CORS)
#
<IfModule mod_headers.c>
  Header merge Vary Origin

  # Allows any origin (just like "*", but works in more cases)
  SetEnvIf Origin "^(http(s)?://[^/:]*(?::\d{1,5})?)?" REQUEST_ORIGIN=$1
  Header always append Access-Control-Allow-Origin %{REQUEST_ORIGIN}e env=REQUEST_ORIGIN

  Header always set Access-Control-Allow-Credentials "true"
  Header always set Access-Control-Allow-Methods "GET, POST, PUT, DELETE"
  Header always set Access-Control-Allow-Headers "*"
  Header always set Access-Control-Expose-Headers "*"
</IfModule>

# Disables Browser caching for production (edit pattern as you wish).
#
#<FilesMatch "\.(html|htm|js|json|css)$">
#   <IfModule mod_headers.c>
#       FileETag None
#       Header unset ETag
#       Header unset Pragma
#       Header unset Cache-Control
#       Header unset Last-Modified
#       Header set Pragma "no-cache"
#       Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
#       Header set Expires "Mon, 10 Apr 1972 00:00:00 GMT"
#   </IfModule>
#</FilesMatch>

注意:我们使用[L]而不是,[L,R=301]因为后者会导致浏览器永久缓存重定向(即使某天该路由是文件,它仍然会被重定向)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.