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 将请求重定向到 index.html(使用视图参数),只有在没有它应该解析到的实际文件的情况下?
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 路由。
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
ErrorDocument 404 /index.html
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 并且它工作正常
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>
julianpoemp.github.io/ngx-htaccess-generator/.
上有一个很棒的“Angular
.htaccess
generator”
生成器是开源的(源代码可以在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
.
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]
.htaccess
配置,例如:
Authorization
header 到
HTTP_AUTHORIZATION
环境变量的翻译。
# 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]
因为后者会导致浏览器永久缓存重定向 (即使有一天该路由是一个文件,它仍然会被重定向)。
angular.module('main', []).config(['$locationProvider', function($locationProvider) {
...
$locationProvider.html5Mode(true);
...
});
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 resource doesn't exist, use index.html
RewriteRule ^ /index.html
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^(www\.)?domain name\.com$ [NC]
RewriteRule ^(.*)$ https://domain name.com/$1 [L,R=301]
#Redirection of requests to index.html
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^(.*) /index.html [NC,L]