使用 .htaccess 重定向到目录中的前端或另一个目录中的 API
Redirect to frontend in directory or API in another directory using .htaccess
我有以下目录结构,其中 /root
作为我的根目录,尽管嵌套在任意数量的子目录中:
- 示例。com/dir1/root
- client/build
- api
当用户导航到 example.com/dir1/root/
时,我希望所有请求都重定向到 example.com/dir1/root/client/build/
但 不更改 URL ,好像 build/
目录内容在 root/
.
中
此外,我希望将 example.com/dir1/root/api/*
之类的所有请求重定向到 example.com/dir1/root/api/
。同样,不更改 URL.
鉴于我对 .htaccess 的工作原理知之甚少,这是我目前的尝试:
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]
# Redirect all requests under /api/ to the API.
RewriteCond %{REQUEST_URI} ^/api/
RewriteRule ^ api/index.php [L]
# If the requested resource doesn't exist, use index.html (html5mode)
RewriteRule ^ client/build/index.html [L]
注意:我已经搜索但没有找到针对此特定情况的任何答案,并且鉴于我对 htaccess 的了解不多,我无法很好地将现有答案拼凑在一起。
index.html
is requesting resources like example.com/dir1/root/assets/style.css
when this resides in /root/client/build/assets/
. Essentially, I want /root/
to behave as if it's actually /root/client/build
, except in the instance /root/api/
is requested.
我会将其实现为 2 个单独的 .htaccess
文件。 “根”目录(即 /dir1/root/.htaccess
)中的一个处理“api”请求并将其他所有内容重写为 client/build
(即“假根”)。 /dir1/root/client/build/.htaccess
中的另一个 .htaccess
文件仅处理应用程序前端内的路由。
例如:
# /dir1/root/.htaccess
RewriteEngine On
# Rewrite all requests under /api/ to the API handler "index.php"
RewriteRule ^api/(?!index\.php) api/index.php [L]
# Rewrite everything else to the "client/build/" subdirectory
RewriteRule (.*) client/build/ [L]
还有...
# /dir1/root/client/build/.htaccess
DirectoryIndex index.html
RewriteEngine On
# Front-controller
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.html [L]
子目录中 .htaccess
文件(包含 mod_rewrite 指令)的存在也有助于防止 rewrite-loop,因为它阻止了父 .htaccess
中的指令成为 re-processed(并一次又一次地将请求重写回 client/build/...
)。
快速查看现有规则...
# 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]
# Redirect all requests under /api/ to the API.
RewriteCond %{REQUEST_URI} ^/api/
RewriteRule ^ api/index.php [L]
# If the requested resource doesn't exist, use index.html (html5mode)
RewriteRule ^ client/build/index.html [L]
您现有规则的问题:
由于第一条规则阻止任何映射到正在处理的文件或目录的请求,它也会阻止对 /dir1/root/
本身(这是一个目录)的请求被重写为 /dir1/root/client/build/index.html
.
条件 RewriteCond %{REQUEST_URI} ^/api/
永远不会成功,因为 REQUEST_URI
服务器变量包含 root-relative URL-path,即。 /dir1/root/api/
.
由于其他所有内容都从“根”重写为 client/build/index.html
,因此也驻留在 client/build/
中的静态资产未正确重写(它们被重写为 index.html
所以可能会导致意外响应)。
您不能在“根”.htaccess
文件中执行文件系统检查,因为与 index.html
相关的静态资产只有在它们被删除后才“存在”重写。
我有以下目录结构,其中 /root
作为我的根目录,尽管嵌套在任意数量的子目录中:
- 示例。com/dir1/root
- client/build
- api
当用户导航到 example.com/dir1/root/
时,我希望所有请求都重定向到 example.com/dir1/root/client/build/
但 不更改 URL ,好像 build/
目录内容在 root/
.
此外,我希望将 example.com/dir1/root/api/*
之类的所有请求重定向到 example.com/dir1/root/api/
。同样,不更改 URL.
鉴于我对 .htaccess 的工作原理知之甚少,这是我目前的尝试:
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]
# Redirect all requests under /api/ to the API.
RewriteCond %{REQUEST_URI} ^/api/
RewriteRule ^ api/index.php [L]
# If the requested resource doesn't exist, use index.html (html5mode)
RewriteRule ^ client/build/index.html [L]
注意:我已经搜索但没有找到针对此特定情况的任何答案,并且鉴于我对 htaccess 的了解不多,我无法很好地将现有答案拼凑在一起。
index.html
is requesting resources likeexample.com/dir1/root/assets/style.css
when this resides in/root/client/build/assets/
. Essentially, I want/root/
to behave as if it's actually/root/client/build
, except in the instance/root/api/
is requested.
我会将其实现为 2 个单独的 .htaccess
文件。 “根”目录(即 /dir1/root/.htaccess
)中的一个处理“api”请求并将其他所有内容重写为 client/build
(即“假根”)。 /dir1/root/client/build/.htaccess
中的另一个 .htaccess
文件仅处理应用程序前端内的路由。
例如:
# /dir1/root/.htaccess
RewriteEngine On
# Rewrite all requests under /api/ to the API handler "index.php"
RewriteRule ^api/(?!index\.php) api/index.php [L]
# Rewrite everything else to the "client/build/" subdirectory
RewriteRule (.*) client/build/ [L]
还有...
# /dir1/root/client/build/.htaccess
DirectoryIndex index.html
RewriteEngine On
# Front-controller
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.html [L]
子目录中 .htaccess
文件(包含 mod_rewrite 指令)的存在也有助于防止 rewrite-loop,因为它阻止了父 .htaccess
中的指令成为 re-processed(并一次又一次地将请求重写回 client/build/...
)。
快速查看现有规则...
# 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] # Redirect all requests under /api/ to the API. RewriteCond %{REQUEST_URI} ^/api/ RewriteRule ^ api/index.php [L] # If the requested resource doesn't exist, use index.html (html5mode) RewriteRule ^ client/build/index.html [L]
您现有规则的问题:
由于第一条规则阻止任何映射到正在处理的文件或目录的请求,它也会阻止对
/dir1/root/
本身(这是一个目录)的请求被重写为/dir1/root/client/build/index.html
.条件
RewriteCond %{REQUEST_URI} ^/api/
永远不会成功,因为REQUEST_URI
服务器变量包含 root-relative URL-path,即。/dir1/root/api/
.由于其他所有内容都从“根”重写为
client/build/index.html
,因此也驻留在client/build/
中的静态资产未正确重写(它们被重写为index.html
所以可能会导致意外响应)。您不能在“根”
.htaccess
文件中执行文件系统检查,因为与index.html
相关的静态资产只有在它们被删除后才“存在”重写。