使用 htaccess 规则用文件扩展名替换查询字符串

问题描述

我有这个链接https://career.guru99.com/top-50-c-sharp-interview-questions-answers/?format=pdf

我想将它重定向https://www.guru99.com/pdf/c-sharp-interview-questions.pdf

我创建了以下 htaccess 规则

RewriteCond %{QUERY_STRING} format=pdf [NC]
RewriteRule ^c-sharp-interview-questions.html  /pdf/c-sharp-interview-questions.pdf? [R=301,L]

但挑战是我有 100 多个链接,我必须在 htacess 中手动添加如此多的条目,这也会减慢网站速度。是否有一些正则表达式可以帮助解决这个问题?

我希望将 /?format=pdf 替换为 .pdf

解决方法

第一个解决方案:如果您在浏览器中点击 http://localhost:80/top-50-c-sharp-interview-questions-answers/?format=pdf,请尝试以下操作。如果您想在浏览器中重定向网址,请将 [NC,L] 更改为 [R=301,NC,L]

RewriteEngine ON
RewriteCond %{HTTP_HOST} ^career\.guru99\.com$ [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [NE,R=301,L]

RewriteCond %{QUERY_STRING} ^format=(.*) [NC]
RewriteRule ^top-50-(.*)/?$ pdf/c-sharp-$1.%1 [NC,L]


第二个解决方案:您能否尝试根据您显示的示例编写以下内容(考虑到您想在浏览器中点击 http://localhost:80/pdf/c-sharp-interview-questions.pdf)。

RewriteEngine ON
RewriteCond %{HTTP_HOST} ^career\.guru99\.com$ [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [NE,L]

RewriteRule ^(pdf)/([^.]*)\.(pdf)/?$ top-50-$1/?format=$2 [NC,L]

注意:请使用第一种解决方案或使用第二种解决方案。请确保在测试您的网址之前清除浏览器缓存。

,

我希望将 /?format=pdf 替换为 .pdf

尽管在您的示例中,这并不是唯一发生变化的事情。您还需要执行以下操作:

  1. 将主机名从 career.guru99.com 更改为 www.guru99.com
  2. 从 URL 路径的开头删除 top-50-
  3. 从 URL 路径的末尾删除 -answers/

尝试以下类似的方法:

RewriteCond %{HTTP_HOST} ^career\.guru99\.com [NC]
RewriteCond %{QUERY_STRING} ^format=(pdf)$ [NC]
RewriteRule ^top-50-([\w-]+)-answers/?$ https://www.guru99.com/%1/$1.%1 [QSD,R=302,L]

这将重定向表单的 URL:

https://career.guru99.com/top-50-something-here-answers/?format=pdf

到:

https://www.guru99.com/pdf/something-here.pdf

%1 反向引用只是从查询字符串中捕获“pdf”字符串(避免重复),这在 RewriteRule substitution 字符串中使用了两次。

$1 反向引用捕获 URL 路径开头的 /top-50- 之后和结尾的 -answers/(尾随斜杠可选)之前的部分 URL 路径URL 路径。

QSD 标志丢弃重定向网址中的查询字符串。

在更改为 301(永久)重定向之前首先使用 302(临时)重定向进行测试 - 如果这是意图 - 以避免潜在的缓存问题。

您需要在测试前清除浏览器缓存。


旁白:

RewriteRule ^c-sharp-interview-questions.html .......

您示例中的 .html 来自哪里?


更新#1:如果最后一个 URL-path 段旨在按原样形成文件名,没有删除任何内容(正如您在评论中暗示的那样),则可以简化上述规则:

RewriteCond %{HTTP_HOST} ^career\.guru99\.com [NC]
RewriteCond %{QUERY_STRING} ^format=(pdf)$ [NC]
RewriteRule ^([\w-]+?)/?$ https://www.guru99.com/%1/$1.%1 [QSD,L]

(但是,这与您在问题中发布的示例相矛盾?)


更新#2:

https://test8.guru99.com/expertadvance-level-qtp-uft-interview-questions/?format=pdf
https://www.test2.demoguru99.com/pdf/qtp.pdf

https://test8.guru99.com/top-35-advanced-software-testing-questions/?format=pdf
https://www.test2.demoguru99.com/pdf/testing.pdf

从这两个示例中,没有可以应用的单一模式将源 URL 路径映射到目标。例如,you 如何用自然语言描述您如何从 expertadvance-level-qtp-uft-interview-questionsqtp 以及从 top-35-advanced-software-testing-questions 到 {{1 }}?

正则表达式不是魔术。需要有一个可识别的“模式”,从 A 映射到 B。

因此您需要单独执行这些重定向。但是,这可以简化,这样它就不会影响站点性能。 (尽管在 testing 中逐字写入 100 个这样的重定向也不算太糟糕。)

您可以在内部将与主机名 (.htaccess) 和查询字符串 (test8.guru99.com) 匹配的请求重写为处理请求并发出重定向的脚本。或者,您可以将请求重写到一个(私有)子目录,该子目录包含仅具有这些特定重定向的第二个 format=pdf 文件。

例如:

在您的根 .htaccess 文件中,如果子目录通过初步检查,则对其进行内部重写:

.htaccess

创建子目录 RewriteCond %{HTTP_HOST} ^test8\.guru99\.com [NC] RewriteCond %{QUERY_STRING} ^format=pdf$ [NC] RewriteRule ^([\w-]+?)/?$ redirect-pdf/$1 [QSD,L] 并在位于 /redirect-pdf 的辅助 .htaccess 文件中创建特定重定向。请注意,在上面的 /redirect-pdf/.htaccess 中,我从重写的 URL 中删除了(可选)尾部斜杠,因此不应在下面的重定向中进行检查。

RewriteRule

如果需要,您可以使用反向引用(如果适用)来保存重复。例如:

RewriteEngine On

# Set an env var to the base target
# (Just saves some bytes/repetition and easier to update)
RewriteRule ^ - [E=TARGET_BASE:https://www.test2.demoguru99.com/pdf]

# Redirects
RewriteRule ^expertadvance-level-qtp-uft-interview-questions$ %{ENV:TARGET_BASE}/qtp.pdf [R=302,L]
RewriteRule ^top-35-advanced-software-testing-questions$ %{ENV:TARGET_BASE}/testing.pdf [R=302,L]
# etc.
# :

# If get to the end and nothing matched above then fail with a 404...?