使用.htaccess优化动态生成URL,实现URL美化
实现搜索URL的友好重写方案
嘿,我知道你已经啃了好几篇关于.htaccess URL重写的帖子,但还是没完全搞明白怎么应用到自己的场景里——这很正常,重写规则确实容易绕晕。咱们直接针对你的需求来拆解,一步步搞定。
先明确目标格式
假设你想要把原来的动态URL:
example.com/search/?itemID=I-123456&itemName=FirstItemName+SecondItemName+MoreItemNames
改成更简洁的“伪静态”格式,比如:example.com/search/I-123456/FirstItemName-SecondItemName-MoreItemNames
如果是其他格式也可以调整,但先以这个最常见的友好格式为例。
第一步:编写.htaccess重写规则
把下面的代码放到你的网站根目录的.htaccess文件里(如果没有就新建一个):
# 启用重写引擎 RewriteEngine On # 设置重写基准(根目录用/即可,子目录需对应调整) RewriteBase / # 规则1:把友好URL转成服务器能识别的动态参数(内部重写,用户无感知) RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^search/([^/]+)/(.+)$ search/?itemID=$1&itemName=$2 [QSA,L,NE] # 规则2(可选但推荐):把旧的动态URL重定向到新的友好URL(利于SEO和用户体验) RewriteCond %{QUERY_STRING} ^itemID=([^&]+)&itemName=(.+)$ RewriteRule ^search/$ search/%1/%2? [R=301,L,NE]
逐个解释规则里的关键部分
你之前看的帖子里提到的RewriteBase、QSA、L这些概念,我结合你的场景给你讲透:
RewriteEngine On:开启Apache的URL重写模块,是所有重写规则的基础前提。RewriteBase /:告诉服务器重写的基准路径是网站根目录,避免路径混乱。如果search目录在子文件夹里(比如example.com/blog/search/),就改成RewriteBase /blog/。RewriteCond %{REQUEST_FILENAME} !-f和!-d:确保当用户访问真实存在的文件或文件夹时,不会触发重写规则——防止正常的文件访问被干扰。^search/([^/]+)/(.+)$:匹配友好URL的正则表达式:^search/:匹配以search/开头的路径([^/]+):捕获第一个参数(itemID),[^/]+表示匹配除斜杠外的所有字符,正好适配你的I-123456格式(.+):捕获第二个参数(itemName),匹配剩下的所有字符,包括里面的连字符
[QSA,L,NE]:QSA:Query String Append,意思是如果用户在友好URL后加了额外参数(比如?sort=price),会自动附加到原动态参数后,不会丢失L:Last,执行完这条规则就停止,不再往下执行其他规则NE:No Escape,避免把特殊字符(比如itemID里的-)转义成编码格式,保证参数正确传递
- 规则2里的
[R=301,L,NE]:R=301表示永久重定向,告诉搜索引擎旧URL已迁移到新URL,利于SEO;末尾的?用来清空原查询字符串,避免重定向后URL带尾巴。
处理itemName里的空格和连字符
原URL里itemName用+(空格的URL编码)分隔,友好URL用-的话,需要在搜索页面代码里做小衔接:
- 生成友好URL时,把itemName里的空格替换成
- - 服务器接收参数时,再把
-替换回空格,就能正确匹配原商品名称
比如PHP里可以这么写:
// 生成友好URL时 $itemName = 'FirstItemName SecondItemName MoreItemNames'; $friendlyItemName = str_replace(' ', '-', $itemName); $friendlyUrl = "/search/{$itemID}/{$friendlyItemName}"; // 接收参数时 $itemName = isset($_GET['itemName']) ? str_replace('-', ' ', $_GET['itemName']) : '';
这样就能完美衔接前后端的参数传递了。
内容的提问来源于stack exchange,提问作者Grant Sharp
相关产品推荐
相关产品推荐

