.htaccess重写返回错误404

时间:2017-07-24 19:37:44

标签: apache .htaccess mod-rewrite

RewriteEngine on
RewriteCond %{QUERY_STRING} (^|&)public_url=([^&]+)($|&)
RewriteRule ^process\.php$ /api/%2/? [L,R=301]

其中domain.tld/app/process.php?public_url=abcd1234是脚本的实际位置。

但我试图让.htaccess像这样制作网址:domain.tld/app/api/acbd1234。 基本上隐藏了process.php脚本和获取查询?public_url

但是上面的脚本返回错误404未找到。

2 个答案:

答案 0 :(得分:2)

我认为这就是你真正想要的:

RewriteEngine on

RewriteCond %{QUERY_STRING} (?:^|&)public_url=([^&]+)(?:$|&)
RewriteRule ^/?app/process\.php$ /app/api/%1 [R=301,QSD]

RewriteRule ^/?app/api/([^/]+)/?$ /app/process.php?public_url=$1 [END]

如果您收到内部服务器错误(http状态500),请检查您的http服务器错误日志文件。有可能你运行的是一个非常旧版本的apache http服务器,你可能不得不用[END]标志替换[L]标志,可能在这个标志中可以正常工作场景。

一般提示:您应该始终更喜欢将此类规则放在http服务器(虚拟)主机配置中,而不是使用动态配置文件(.htaccess样式文件)。这些文件非常容易出错,难以调试,它们确实会降低服务器的速度。只有在您无法控制主机配置(读取:非常便宜的托管服务提供商)或者您的应用程序依赖于编写自己的重写规则(这是一个明显的安全噩梦)的情况下,它们才被支持作为最后一个选项。 )。

更新:

基于您在下面评论中的许多问题(我们再次看到在问题本身中确切的重要性;-))我添加了这个变体,实现了对路径组件的不同处理:

RewriteEngine on

RewriteCond %{QUERY_STRING} (?:^|&)public_url=([^&]+)(?:$|&)
RewriteRule ^/?app/process\.php$ /api/%1 [R=301,QSD]

RewriteRule ^/?api/([^/]+)/?$ /app/process.php?public_url=$1 [END]

答案 1 :(得分:1)

  

我想让.htaccess像这样制作网址:example.com/app/api/acbd1234

你不能在.htaccess中这样做。您更改应用程序中的URL,然后将新URL重写为实际/旧URL。 (如果旧的URL已经被搜索引擎编入索引,你只需要重定向它 - 但你需要注意重定向循环。)

因此,请将应用程序中的URL更改为/app/api/acbd1234,然后在.htaccess中重写(我假设在您的/app子目录中)。例如:

RewriteEngine On

# Rewrite new URL back to old
RewriteRule ^api/([^/]+)$ process.php?public_url=$1 [L]

您在早期的指令中包含了一个尾部斜杠,但是您在示例网址中省略了这一点,所以我也在这里省略了它。

如果您还需要为了SEO而重定向旧URL,那么您可以在内部重写之前实现重定向:

RewriteEngine On

# Redirect old URL to new (if request by search engines or external links)
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} (?:^|&)public_url=([^&]+)(?:$|&)
RewriteRule ^process\.php$ /app/api/%1? [R=302,L]

# Rewrite new URL back to old
RewriteRule ^api/([^/]+)$ process.php?public_url=$1 [L]

REDIRECT_STATUS的检查是为了避免重写循环。带括号的子模式中的?:可以避免将组捕获为反向引用。

只有当您确定它正常工作时才将302(临时)更改为301(永久),以避免浏览器缓存错误的重定向。