我有一个带有 URL 参数的单页网站,它仍应打开单个 index.html(使用 Vue.JS 和 Vue.JS Router 制作)。例如,有www.example.com/
、www.example.com/user
和www.example.com/user/project/myproject
。现在,正如您可能预料的那样,我无法将其与我的 .htaccess 文件一起使用。
我尝试了很多方法来实现这个功能:
Order allow, deny
Deny from all
<FilesMatch ^(index\.html)?$>
Allow from all
</FilesMatch>
IndexIgnore *
DirectoryIndex index.html
这没有任何作用。然后我用以下内容替换了 .htaccess 文件的内容:
RewriteEngine On
RewriteRule ^$ index.html/ [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.html/$1 [QSA,L]
Options All -Indexes
它改变了一些东西,但不是正确的东西。www.example.com/user
因为显然找不到目录,所以给出了 HTTP 错误 404。
我的目标
像这样的树:
├───assets
├───downloads
│index.html
│robots.txt
我希望能够仅访问index.html
用于任何参数组合的。访问assets
和downloads
应该是可访问的,因为人们应该能够正确查看页面并下载他们想要的内容。assets
包含静态资源,同样适用于downloads
。
我查看了大量资料,但似乎没有一个能给我完美的结果。我希望你能帮助我。
谢谢你的时间!
更新
结合 MrWhite 和 Lacek 的答案似乎可以解决问题,但现在有一个重大问题。所有文件似乎都与 index.html 的内容一起加载。因此,每个图像、js、CSS 等都有一个 HTML、BODY、HEAD、DIV、SCRIPT(等等)标签作为数据,而不是它们的实际数据,例如图像的像素数据。
这就是我.htaccess
现在的样子:
Options All -Indexes
DirectoryIndex index.html
<Files index.html>
AcceptPathInfo On
</Files>
RewriteEngine On
RewriteRule ^index\.html - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.html [L]
虚拟主机配置(域名审查):
<VirtualHost *:80>
ServerAdmin [email protected]
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example/html
AliasMatch "/.*" "/var/www/example/html/index.html"
Alias "/assets" "/var/www/example/html/assets/"
Alias "/downloads" "/var/www/example/html/downloads/"
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
查看下面和答案下面的评论以获取更多背景信息。
来源
ServerFault - 301 将整个域重定向到单个页面 .HTACCESS
ServerFault-带有参数的多个页面的 htaccess 重写规则
答案1
assets
确实是静态资源。
如果您的“资产”是客户端静态资源(例如 CSS、JS 和图像),那么您就无法阻止它们,.htaccess
因为它们需要公开访问才能供客户端 HTML 访问。(?)
RewriteRule ^$ index.html/ [QSA,L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.html/$1 [QSA,L]
这将传递请求的 URL 作为附加路径名信息(即路径信息)到index.html
,例如请求/foo/bar
,它会将请求发送到index.html/foo/bar
。这里的问题是默认text/html
处理程序不接受路径信息默认情况下将触发 404。
但是 Vue.JS 可能不需要将其作为路径信息 - 它可能简单地按照您的建议“扫描 URL”。在这种情况下,您可以简化指令,例如:
Options All -Indexes
DirectoryIndex index.html
RewriteEngine On
RewriteRule ^index\.html - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.html [L]
这是一个更“标准”的前端控制器。QSA
这里不需要标志。
这会将未映射到文件或目录的所有内容重写为index.html
。第一个RewriteRule
只是一种优化,以防止对重写的请求进行index.html
重新测试。
您不需要明确重写根请求(即RewriteRule ^$ index.html/
),因为 mod_dir 将通过指定的内部子请求执行此操作DirectoryIndex index.html
。
答案2
尝试这个:
Alias "/download" "/wherever/your/app/is/download/"
AliasMatch "/.*" "/wherever/your/app/is/index.html"
这些指令将路由除文件之外的所有/download/*
内容index.html
。
这些必须包含在VirtualHost
配置中,而不是.htaccess
文件中。请注意,使用该Alias
指令时,您必须使用完整的文件系统路径,而不是 webroot 下的相对路径。
另外,正如@MrWhite 指出的那样,您可能希望明确启用 html 页面的 PathInfo 的使用,如下所示:
<Files index.html>
AcceptPathInfo On
</Files>