htaccess重定向Angular路由

时间:2014-03-30 02:10:46

标签: angularjs .htaccess redirect web-applications routing

我有一个带有多个路径的角度应用程序,例如:

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(带有视图参数),只有当它没有应该解析的实际文件时?

7 个答案:

答案 0 :(得分:124)

使用以下代码段:

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

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

如果有资源,这将跳转到实际资源,并且对于所有AngularJS路由,将跳至index.html

答案 1 :(得分:19)

如果应用请求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

答案 2 :(得分:4)

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

ErrorDocument 404 /index.html

答案 3 :(得分:2)

点击此链接:https://stackoverflow.com/a/49455101/5899936 在根文件夹中创建PagerTabStrip pt= container.findViewById(R.id.pager_tab_strip); pt.getChildAt(0).setRotationY(180); pt.getChildAt(1).setRotationY(180); pt.getChildAt(2).setRotationY(180); 文件,并在.htaccess

中添加此文件
.htaccess

答案 4 :(得分:2)

就我而言,我创建如下的.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,就可以了

答案 5 :(得分:0)

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

答案 6 :(得分:0)

就我而言,我们需要更多功能达到Authorization的配置,例如:

  • 强制使用HTTPS协议(在下面进行注释)。
  • 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)$"> # <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> 环境变量。
  • 跨域资源共享(CORS)。
  • 并禁用了对特定格式的缓存(也已注释掉)。
[L]

注意:我们使用[L,R=301]代替export default class Pro extends React.Component { constructor(props) { super(props); this.state = { email: '', username: '', }; } _onPressButton = () =>{ this.props.navigation.navigate('Profile'); } render() { return ( <Block row style={styles.main}> <Block> <Image source={{ uri: Images.ProfilePicture }} style={styles.avatar} /> </Block> <Block center> <TouchableOpacity onPress={this._onPressButton()} underlayColor="white"> <Text>User name</Text> <Text>Email</Text> </TouchableOpacity> </Block> </Block> ); } } ,因为后者会导致浏览器永久缓存重定向 (即使某天该路由是文件,它仍将被重定向)。