如何将带参数的链接重写为独立友好链接(保留ID参数)
要把https://domainname.com/article.html?id=5改成https://domainname.com/article/title-of-article-here这种友好URL,同时保留ID用于后端逻辑,确实不能只靠.htaccess,得结合后端数据库和跳转逻辑,下面是一步步的实操方案:
一、Apache服务器的.htaccess配置
先在网站根目录的.htaccess里加基础重写规则:
1. 开启重写引擎
RewriteEngine On RewriteBase /
2. 把友好URL转发到后端处理文件
不管你用PHP、Python还是其他后端,先把/article/xxx这种请求转到对应的处理脚本(这里以PHP为例):
# 排除真实存在的文件和目录,避免静态资源被重写 RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d # 把/article/后面的标题部分作为title参数传给article.php RewriteRule ^article/([^/]+)$ article.php?title=$1 [L,QSA]
如果非要用原来的.html文件,把规则里的article.php换成article.html就行,但更建议用后端脚本处理,灵活性更高。
3. 旧链接的跳转(建议后端处理,.htaccess仅作辅助)
.htaccess没法直接从数据库拿标题,所以旧链接article.html?id=5转友好URL的逻辑,最好放到后端做,后面会说。如果非要用.htaccess临时占位,规则是这样的(但实际标题得靠后端补):
RewriteCond %{QUERY_STRING} ^id=(\d+)$ RewriteRule ^article\.html$ /article/temp-title-for-id-%1? [L,R=301]
二、后端核心逻辑(以PHP为例)
这部分是关键,要实现“从标题找ID”和“旧链接跳新URL”两个功能:
1. 从友好URL的标题获取文章ID
首先数据库里要给文章加个url_title字段,专门存处理后的标题——比如把“我的第一篇技术文”改成wo-de-di-yi-pian-ji-shu-wen(全小写、空格换短横线、删特殊字符),而且要给这个字段加唯一约束,保证每个标题对应唯一ID。
然后在article.php里写查询逻辑:
<?php // 连接数据库(这里用mysqli示例,PDO同理) $conn = mysqli_connect('localhost', 'user', 'password', 'db_name'); // 获取URL里的标题参数 $urlTitle = $_GET['title'] ?? ''; // 清理参数防止SQL注入 $cleanTitle = mysqli_real_escape_string($conn, $urlTitle); // 根据处理后的标题查文章ID和内容 $query = "SELECT id, title, content FROM articles WHERE url_title = '$cleanTitle'"; $result = mysqli_query($conn, $query); $article = mysqli_fetch_assoc($result); if (!$article) { // 标题不存在,返回404页面 header("HTTP/1.0 404 Not Found"); include '404.html'; exit; } // 现在你拿到了文章ID $article['id'],可以继续原来的业务逻辑了 // 比如渲染文章内容:echo $article['content']; ?>
2. 旧链接自动跳转到友好URL
如果用户访问旧的article.html?id=5,在article.html(或者对应的后端脚本)里加跳转逻辑:
<?php $conn = mysqli_connect('localhost', 'user', 'password', 'db_name'); if (isset($_GET['id'])) { $articleId = (int)$_GET['id']; // 根据ID查对应的处理后标题 $query = "SELECT url_title FROM articles WHERE id = $articleId"; $result = mysqli_query($conn, $query); $article = mysqli_fetch_assoc($result); if ($article) { $friendlyUrl = "/article/" . $article['url_title']; // 用301永久跳转,告诉搜索引擎更新索引,利于SEO header("HTTP/1.1 301 Moved Permanently"); header("Location: $friendlyUrl"); exit; } } // 下面放原来的文章展示代码 ?>
三、前端链接统一替换
把网站里所有指向文章的链接,都改成友好URL格式,比如:
<a href="/article/wo-de-di-yi-pian-ji-shu-wen">我的第一篇技术文</a>
别再用带?id=xxx的旧链接了,不然用户点了又跳一遍,体验不好。
四、其他注意事项
- Nginx服务器的适配:如果用Nginx,把.htaccess的规则换成Nginx的rewrite:
location / { rewrite ^/article/([^/]+)$ /article.php?title=$1 last; } # 旧链接跳转同样建议后端处理,这里仅作示例 location = /article.html { if ($args ~* "^id=(\d+)$") { set $id $1; rewrite ^ /article/temp-title-$id? permanent; } } - 标题处理工具:生成
url_title的时候,可以用现成的函数,比如PHP的urlencode配合字符串替换,或者专门的slug生成库,确保标题符合URL规范。 - 404页面:一定要处理标题不存在的情况,返回标准404,别让服务器报错。
内容的提问来源于stack exchange,提问作者MaxCat

