【问题标题】:Absolute URL from base folder with rewrite带有重写的基本文件夹的绝对 URL
【发布时间】:2016-08-27 00:35:24
【问题描述】:

我有一个在 WampServer 上本地运行的项目。这是一个类似 MVC 的结构;它将 URL 重写为index.php?url=$1。满员.htaccess:

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]

当我想使用 PHP location: <location> 将用户发送到另一个页面时,由于重写,它不能正确执行此操作(尽管从技术上讲,我总是在 index.php)。

例如,如果我在 http://localhost/project_name/controller/method/ 并且此控制器的构造函数或方法尝试将我发送到:

  • header('location: another_controller/method'); 发送给我 http://localhost/project_name/controller/method/another_controller/method/
  • header('location: /another_controller/method'); 发送给我 http://localhost/another_controller/method/

但我希望它像这样发送给我:

  • header('location: /another_controller/method'); 发送给我 http://localhost/project_name/another_controller/method/

现在我找到的唯一解决方案是:

define('BASE_URL','http://localhost/project_name');
header('location: '.BASE_URL.'/another_controller/method/');

但这也不是完美的,因为每当域或文件夹名称发生更改时,我都必须更改此定义的常量BASE_URL。我也可以在我的 BaseController 中创建一个创建绝对 URL 的方法,但这个方法基本上也只是在 BASE_URL 前面添加。

注意: HTML 的srchref 属性不会出现同样的问题,它们可以使用相对路径(路径中没有project_name 文件夹)。但是我不明白为什么。因为如果标题 location 导致浏览器将相对 URL 附加到当前位置,为什么它在查找 .css.js 文件时没有相同的行为。

所以...这向我提出了几个问题:

  1. 如果我有虚拟主机,我会遇到这个问题吗?
  2. 解决此问题的最佳方法是什么?
  3. 最好只有完整的绝对 URL?
  4. 为什么 HTML 的 srchref 属性不具有这种行为?

【问题讨论】:

  • 你能从开始添加一些你的htaccess文件的代码吗??
  • @HarshSanghani 已添加。
  • 能否在 RewriteEngine on 后添加 RewriteBase /project_name/
  • @HarshSanghani 这没有解决。 header('location: /'); 仍然是 http://localhost/ 而不是 http://localhost/project_name/
  • 我注意到你说“header('location: another_controller/method'); 将我发送到http://localhost/project_name/controller/method/another_controller/method/”我想指出这将永远是这种情况 - 你忘记了前导斜线。如果没有前导斜杠,它将始终是从当前 URL 开始的相对重定向。不确定这是错字还是完全不相关,但我想我会指出来。

标签: php .htaccess mod-rewrite relative-path absolute-path


【解决方案1】:

现在我找到的唯一解决方案是:

define('BASE_URL','http://localhost/project_name');
header('location: '.BASE_URL.'/another_controller/method/');

但这也不完美,因为它让我不得不改变 每当域或文件夹名称时,此定义的常量 BASE_URL 变化。

您不需要更改定义的常量。这些值可以动态找到。

示例:

if ($_SERVER['DOCUMENT_ROOT'] == dirname($_SERVER['SCRIPT_FILENAME'])) {
    define('BASE_PATH', '/');
} else {
    define('BASE_PATH', dirname($_SERVER['SCRIPT_NAME']) . '/');
}

$protocol = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';
define('BASE_URL', $protocol . $_SERVER['SERVER_NAME'] . BASE_PATH);

此外,您可以将重定向包装到一个可以同时处理两者的函数中,而不用担心是否指定绝对 URL 或路径:

function redirect($path = null) {
    if (isset($path)) {
        if (filter_var($path, FILTER_VALIDATE_URL)) {
            header('Location: ' . $path);
        } else {
            header('Location: ' . BASE_URL . $path);
        }
    } else {
        header('Location: ' . BASE_URL);
    }
    exit;
}

最后,正如 @HarshSanghani 在 cmets 中提到的,.htaccess 文件中的基本路径应该与代码中的基本路径匹配。所以如果BASE_PATH(基于上面的例子)输出/project_name/,那么你的.htaccess应该适应它:

RewriteBase /project_name/

【讨论】:

    【解决方案2】:

    回答您的问题:

    1. 这取决于您的虚拟主机的配置方式。
    2. 您可以简单地动态生成 BASE_URL:$baseUrl = dirname($_SERVER['SCRIPT_NAME']);。这样,如果您的文件夹或域发生更改,您就不必更改任何代码。
    3. 您不需要域部分。
    4. html srchref 由您的浏览器解释,其中考虑了页面的 <base> 标记。带有<base> 标签的页面上的所有路径都会被您的浏览器相应地更改。

    您从服务器发送的 HTTP 标头(用于重定向)与您发送的 html 页面无关,因此不会更新。

    【讨论】:

      【解决方案3】:
      1. 如果您将项目设置在子目录中,您将遇到此问题。如果您想在 project_name.localhost 上设置虚拟主机,那么使用虚拟主机可以解决这个问题。
      2. 在我的项目中,我使用环境变量来加载不同的配置文件以进行开发、登台或生产。在此我以某种方式设置了$baseUri
      3. 最好使用绝对 URL(包括域)来解决此问题和 SEO。就功能而言,您不需要域部分。
      4. src 和 href 标签的工作方式通常相同,但正如 Andreas 所说,它们可能会受到基本标签的影响。

      【讨论】:

        【解决方案4】:

        您应该在 htaccess 文件中指定 RewriteBase。在链接中使用相对路径,您不需要更多。

        RewriteBase /project_name/
        RewriteEngine on
        RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-l
        RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-09-28
          • 2013-11-13
          • 2015-06-24
          • 2019-07-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-05-23
          相关资源
          最近更新 更多