angularjs Angular 路由的htaccess重定向

mkh04yzy  于 2022-10-31  发布在  Angular
关注(0)|答案(8)|浏览(202)

我有一个有Angular 的应用程序,有几条路线,例如:

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

使用angular的html5路由模式,当你点击应用程序中的链接时,这些错误可以正确解析,但是当你进行硬刷新时,当然会出现404错误。

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

这适用于Angular 请求,但是当我试图加载脚本或在我的域中进行 AJAX 调用时,例如:

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

这个脚本没有加载-它的请求被重定向,它试图加载index.html页面,因为.htaccess认为它应该重新路由请求-不知道这个文件确实存在,它应该加载这个文件而不是重定向。
有没有什么方法可以让htaccess只在没有实际的文件可以解析的情况下,才将请求重定向到index.html(使用视图参数)?

92dk7w1h

92dk7w1h1#

使用类似以下的代码片段:

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路由)。

bvjveswy

bvjveswy2#

如果应用程序请求了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
zphenhs4

zphenhs43#

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

ErrorDocument 404 /index.html
4szc88ey

4szc88ey4#

在我的情况下,我创建.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)中,它运行良好

3pvhb19x

3pvhb19x5#

请查看此链接: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>
1aaf6o9v

1aaf6o9v6#

我将提供另一个详细的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]
h79rfbju

h79rfbju7#

julianpoemp.github.io/ngx-htaccess-generator/上有一个很棒的 “Angular .htaccess发电机”
该生成器是开源的(源代码可以在github.com/julianpoemp/ngx-htaccess-generator上找到)。
默认情况下,生成的.htaccess如下所示,对我来说很好用:


# Generated with ngx-htaccess-generator v1.2.0

# Check for updates: https://julianpoemp.github.io/ngx-htaccess-generator/

# 

# Transparency notice: Some parts were extracted from

# Apache Server Configs v5.0.0 | MIT License

# https://github.com/h5bp/server-configs-apache

# Extracted parts are wrapped by "START Extract from ASC"

<IfModule mod_rewrite.c>
  RewriteEngine On

  # Redirection of requests to index.html
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
  RewriteRule ^.*$ - [NC,L]
  # Redirect all non-file routes to index.html
  RewriteRule ^(?!.*\.).*$ index.html [NC,L]
</IfModule>

使用Angular 13.0.3成功测试。

tzdcorbm

tzdcorbm8#

在我的例子中,我们需要一个更多的功能达到.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)$">

# # Ensures "Expires" header is not overridden by module.

# <IfModule mod_expires.c>

# ExpiresActive Off

# </IfModule>

# <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],因为后者会导致浏览器永久缓存重定向(即使某一天该路由是一个文件,它仍然会被重定向)。

相关问题