如何在CodeIgniter中移除URL中的问号?已通过.htaccess去除index.php
这种情况我在维护CodeIgniter项目的时候碰到过好几次,核心问题一般出在URL重写规则的匹配逻辑或者CodeIgniter的URI解析配置上——毕竟普通用户访问正常但爬虫出现异常,说明请求头或解析逻辑在爬虫场景下有差异。下面一步步给你排查和解决的方案:
1. 先确认CodeIgniter核心配置是否正确
打开application/config/config.php文件,检查两个关键配置:
- 确保
$config['index_page']是空字符串:
如果这里还保留着$config['index_page'] = '';'index.php',即使htaccess做了重写,也可能在某些请求场景下出现解析异常。 - 调整
$config['uri_protocol']设置:
默认的'AUTO'在大部分环境下没问题,但如果爬虫请求的URI解析异常,可以尝试改成'REQUEST_URI':
有些服务器环境下$config['uri_protocol'] = 'REQUEST_URI';'PATH_INFO'会导致CI无法正确识别路径,进而生成带多余问号的URL。
2. 检查URL重写规则(分服务器类型)
这是最容易出问题的地方,很多人写的规则会在无查询字符串的请求里引入多余问号:
Apache服务器(.htaccess)
正确的规则应该是这样的:
RewriteEngine On RewriteBase / # 跳过真实存在的文件和目录,避免静态资源被重写 RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d # 关键:用斜线分隔index.php和后续路径,不要用问号 RewriteRule ^(.*)$ index.php/$1 [L]
如果你的规则里写的是index.php?$1,那当请求没有查询字符串时,就会出现/?/xxx这种格式——这正是你碰到的问题!把问号改成斜线就解决了。
Nginx服务器
对应的location配置要这么写:
location / { try_files $uri $uri/ /index.php$uri; }
同样要避免写成/index.php?$uri,否则会引入多余问号。
3. 排查爬虫请求的真实来源
有时候爬虫抓取的是旧的历史URL(比如之前没移除index.php时的链接,如index.php?/category/xxx),这时可以在Google站长工具里提交这些异常URL的移除请求,同时确保网站内部所有链接都是用site_url()或base_url()生成的,避免硬编码错误的URL格式。
你也可以查看服务器的访问日志,看看爬虫请求的原始URL是什么——如果是GET /index.php?/category/xxx HTTP/1.1这种,那说明重写规则把index.php?替换成了/?,这就回到第二步的规则修正上了。
4. 验证修复效果
修改配置和规则后,手动在浏览器里输入www.example.com/?/category/subcategory/product/,看是否会自动跳转到正常的无问号URL,或者返回和正常URL一样的内容。然后用Google站长工具的URL检查工具测试这个异常URL,确认服务器返回的状态码是200(或者301重定向到正常URL),这样爬虫就会逐步更新索引,不再显示带问号的URL了。
内容的提问来源于stack exchange,提问作者Dipesh Sanghani

