.htaccess 删除 php 文件扩展名仅在 heroku 上不起作用

.htaccess 删除 php 文件扩展名仅在 heroku 上不起作用

因此,我在本地 apache XAMPP 服务器根目录中的 .htaccess 文件中写入了以下代码,并且它 100% 正确运行。但是,当我尝试部署到 Heroku 时,它不起作用。我尝试过在互联网上找到的略微修改过的版本来执行相同的操作,但似乎都不起作用。这应该会删除文件扩展名并允许诸如文件存在的位置之类的.php内容,并且只需使用 PHP 读取它们并根据它们的内容返回输出。/api/products/allapi.phpproducts/all$_SERVER['PATH_INFO']

Options +MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]

我对此了解不多,.htaccess因此如果能提供任何帮助我将非常感激。

答案1

这应该会删除 .php 文件扩展名

严格来说,此代码旨在添加文件.php扩展名重新返回(以便路由 URL)。(您已通过发出请求将其“删除” /api/products/all。)

但是,这段代码并没有像你想象的那样工作。由于该MultiViews行(mod_negotiation 的一部分),它只能在你的本地服务器上工作。后面的 mod_rewrite 代码根本没有做任何事情,这可能是为什么它在 Heroku 上无法正常工作的原因?

如果允许 mod_rewrite 指令运行(MultiViews已禁用/api/products/all),那么这将重写对的请求/api/products/all.php,这在此示例中显然是不正确的。

/api/products/all我不知道您正在尝试处理什么其他 URL 格式,但是为了使用 mod_rewrite专门路由表单的 URL /api.php/products/all,您将需要类似下面的内容:

RewriteEngine On
RewriteRule ^(api)/(.+) $1.php/$2 [L]

RewriteCond如果您仅匹配这个特定的 URL,则不需要这些指令。

...并且“products/all”只是用 php 读入的

这称为额外的路径名信息并由服务器管理/收集,并通过超全局变量PATH_INFO的元素传递给 PHP $_SERVER。是否允许路径信息完全取决于服务器。(如果不允许,则此类 URL 将导致 404。)

更新#1:

...如果我还有诸如 example.js.php 之类的文件(我使用 php 代码,但将它们呈现为 javascript 文件)并且我想删除它们的 .php 以便可以通过 example.js 访问它们,我该如何修改重写规则?

您可以添加如下所示的附加规则块:

RewriteCond %{DOCUMENT_ROOT}/$1.$2.php -f
RewriteRule (.+)\.(js)$ $1.$2.php [L]

这会拦截所有文件请求,并且如果存在则将.js请求重写到相应的文件。.js.php

或者,您可以RewriteCond像这样指定指令:

RewriteCond %{REQUEST_FILENAME}.php -f

请注意,如果您的.js文件也位于以以下方式开始的 URL 路径下/api/,则此规则将需要执行上述规则路由您的 API 调用,以避免冲突。

更新#2:您可能还需要为这些资源设置正确的 mime 类型。(使用错误的 mime 类型是否有效取决于浏览器。)由于 URL.js正在内部重写为 PHP 脚本(即.js.php),Apache 自然会使用text/htmlmime 类型来提供此服务(默认情况下它对所有 PHP 文件都这样做)。您可以确保在脚本中明确设置正确的标头,也可以使用指令 (mod_headers)Content-Type进行设置。例如:.htaccessHeader

<FilesMatch "\.js.php$">
    Header set Content-Type "application/javascript; charset=UTF-8"
</FilesMatch>

请注意,这只适用于 Apache 2.2.12+(在此版本之前,根本无法使用指令设置标题Content-TypeHeader

T还要注意,使用标志设置 mime 类型的“更简单”方法RewriteRule在每个目录/上下文中不起作用.htaccess- 当重写过程重新开始时它会被覆盖。

相关内容