如果不存在,则在重写后添加正斜杠

问题描述

我已经阅读了大量的文章并尝试了大量的解决方案,但找不到适合我需求的解决方案。

在我的 htaccess 中,我有以下内容

const getJSON = (url) => fetch(url).then(res => res.json()); // Returns a Promise
Promise.all([getJSON("users.json"),getJSON("tasks.json")]).then((JSONs) => {
  // After some unkNown time... Both fetch Promises are resolved.  
  // Do some work with both JSON data:
  console.log(JSONs); // In the exact order as the functions calls array
});

这很好用,除了 1 个小问题。

如果 RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^profile/([\w-]+)/?$ profile.PHP?username=$1 [L,QSA] RewriteRule ^profile/([\w-]+)/([\w-]+)/?$ profile.PHP?username=$1&type=$2 [L,QSA] RewriteRule ^profile/([\w-]+)/([\w-]+)/([\w-]+)/?$ profile.PHP?username=$1&type=$2&o=$3 [L,QSA] 没有 profile/username,除非使用绝对网址,否则页面上的链接将中断。所以 / 最终会变成 <a href="./1"> 而不是 profile/1

如果我将第一次重写改为如下:

profile/username/1

然后 RewriteRule ^profile/([\w-]+)/$ profile.PHP?username=$1 [L,QSA] 将返回一个我不想要的 404 - 如果它不存在,我希望它强制 / 结束。

我尝试添加

https://myurl/username

我试过了

RewriteRule ^(.*)([^/])$ /$1$2/ [L,R=301] 

在重写条件已经到位的情况下,无法弄清楚如何做到这一点。

解决方法

要在您的 profile 网址末尾添加可选的 traling,您可以使用此

RewriteEngine on

RewriteCond %{REQUEST_URI} ^/profile/
RewriteRule !/$ %{REQUEST_URI}/ [L,R]
,

如果 profile/username 没有 /,除非使用绝对网址,否则页面上的链接将中断。所以 <a href="./1"> 最终会变成 profile/1 而不是 profile/username/1

如果问题仅适用于 /profile/<username> 形式的 URL,那么我会具体并且只将尾部斜杠附加到这些特定 URL,否则,您将获得大量重定向(这可能是有害的)到 SEO)。

但是,您应该确保内部链接指向规范 URL(即带有尾部斜杠)。

例如,以下应该在您现有的重写之前

RewriteRule ^(profile/[\w-]+)$ /$1/ [R=301,L]

由于规范 URL 需要尾部斜杠,因此应该是 301(永久)重定向。 (但先用 302 测试。)


或者,不是在 .htaccess 中重定向(如果您仍在内部链接到无斜杠的 URL),那么您可以将 base 元素(包括尾部斜杠)添加到 {{1} } 部分来说明应该相对于哪些相对 URL。

例如:

head

旁白:

<base href="/profile/<username>/">

这两个 RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^profile/([\w-]+)/?$ profile.php?username=$1 [L,QSA] RewriteRule ^profile/([\w-]+)/([\w-]+)/?$ profile.php?username=$1&type=$2 [L,QSA] RewriteRule ^profile/([\w-]+)/([\w-]+)/([\w-]+)/?$ profile.php?username=$1&type=$2&o=$3 [L,QSA] 指令似乎完全是多余的。 RewriteCond 指令仅适用于后面的第一个 RewriteCond。但是RewriteRule 模式无论如何都不太可能匹配真实文件(除非您的文件没有扩展名或目录同名)。

,

很遗憾,我无法真正实现我所希望的目标,因为可能存在也可能不存在多个级别的变量。

部分我使用了 Amit 提供的解决方案:

RewriteCond %{REQUEST_URI} ^/profile/
RewriteRule !/$ %{REQUEST_URI}/ [L,R]

然而,这还不够,因为正如 MrWhite 所指出的,有 3 个单独的潜在网址。

https://myurl/profile/username/
https://myurl/profile/username/type/
https://myurl/profile/username/type/o/

在此站点中,用户名应始终存在,但类型和 o 可能存在也可能不存在。

所以我所做的是检测 url 的级别,然后创建条件 .和 .. 使用 php。

变量 o 始终是数字,变量类型从不是数字,所以这对我有用。

if (isset($_GET['o'])) { $o = strip_tags($_GET['o']); }
elseif (isset($_GET['type']) && is_numeric($_GET['type'])) { $o = strip_tags($_GET['type']); }

然后我检测到:

// if o is set or if type is numberic,use ..
if (isset($_GET['o']) || (isset($_GET['type']) && is_numeric($_GET['type']))) {
  $dots = '..';
// if o is not set and type is not numeric just use .
} else {
  $dots = '.';
}

<a href="'.$dots.'/1/">1</a> 的最终结果:

if url is https://myurl/profile/username/
result is https://myurl/profile/username/1/

if url is https://myurl/profile/username/3/
result is https://myurl/profile/username/1/

if url is https://myurl/profile/username/type/3/
result is https://myurl/profile/username/type/1/

这是想要的结果。