URL查询字符串首次加载或久置后异常变更的原因排查求助
问题分析与解决方案
问题背景
当用户从WhatsApp等外部平台点击网站文章/活动链接时,URL的GET参数(如?i=test-invite)在页面加载完成后会变为一串0%0开头的null字符;页面久置后刷新也会出现该问题,但站内导航正常。测试环境为Google Chrome浏览器,主机是InfinityFree。
为缩短URL长度,页面文件命名为i.php,GET参数设为i而非url。已尝试添加/移除urlencode函数,问题仍存在。
核心代码如下:
$page_url = urlencode($_GET['i']); if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['i'])) { $myEvent = $mysqli->prepare('SELECT * FROM event WHERE url=?'); $myEvent->bind_param('s', $page_url); if ($myEvent->execute()) { $result = $myEvent->get_result(); if ($result->num_rows == 1) { $row = $result->fetch_assoc(); // Fetch Primary Database Data $id = $row['id']; $account_id = $row['account_id']; $url = $row['url']; // Fetch Other Database Data $title = $row['title']; $desc = $row['description']; $date_time_start = $row['date_time_start']; $date_time_end = $row['date_time_end']; $location = $row['location']; $locationPin = $row['locationPin']; $colour = $row['bg_colour']; $image = $row['bg_image']; } } $myEvent->close(); }
问题原因与代码错误
- 二次编码导致参数异常:PHP会自动解码GET参数,对
$_GET['i']再次调用urlencode会让参数被二次编码,无法匹配数据库中存储的原始值,外部平台的链接触发服务器缓存或重写规则时,就会显示为null字符。 - InfinityFree主机缓存/重写干扰:免费主机的自动缓存或URL重写规则,对外部来源的链接参数处理异常,久置刷新触发缓存更新时也会出现同样问题;站内导航因内部请求绕过了这套逻辑,所以正常。
- 代码执行顺序错误:在判断
$_GET['i']是否存在前就执行urlencode($_GET['i']),参数不存在时会抛出Notice错误,可能干扰服务器参数处理流程。
解决方案
- 移除多余的
urlencode调用
直接使用PHP自动解码后的参数值,修改代码如下:
if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['i'])) { $page_url = $_GET['i']; $myEvent = $mysqli->prepare('SELECT * FROM event WHERE url=?'); $myEvent->bind_param('s', $page_url); // 后续执行逻辑保持不变 if ($myEvent->execute()) { $result = $myEvent->get_result(); if ($result->num_rows == 1) { $row = $result->fetch_assoc(); // 数据赋值逻辑... } } $myEvent->close(); }
- 添加参数合法性校验
过滤非法字符,避免异常参数传入:
$page_url = preg_replace('/[^a-zA-Z0-9-_]/', '', $_GET['i']);
- 禁用页面缓存
在i.php头部添加缓存禁用响应头,避免主机缓存错误参数:
header("Cache-Control: no-cache, no-store, must-revalidate"); header("Pragma: no-cache"); header("Expires: 0");
- 检查.htaccess规则
确认网站的URL重写规则没有对i.php的i参数进行错误转换,比如删除任何可能修改该参数的重写规则。
优化建议
- 处理参数缺失/非法情况:当参数不存在或不合法时,跳转至404或首页,避免页面空白:
if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['i'])) { $page_url = preg_replace('/[^a-zA-Z0-9-_]/', '', $_GET['i']); if (empty($page_url)) { header("Location: /404.php"); exit; } // 数据库查询逻辑... } else { header("Location: /index.php"); exit; }
- **避免使用SELECT ***
明确指定需要查询的字段,减少数据传输开销:
$myEvent = $mysqli->prepare('SELECT id, account_id, url, title, description, date_time_start, date_time_end, location, locationPin, bg_colour, bg_image FROM event WHERE url=?');
- 完善数据库错误处理
添加错误捕获,方便排查问题:
if (!$myEvent) { die('Prepare failed: ' . $mysqli->error); } if (!$myEvent->execute()) { die('Execute failed: ' . $myEvent->error); }
- 切换至HTTPS协议
WhatsApp等平台对HTTPS链接兼容性更好,能避免HTTP协议可能导致的参数解析异常,同时提升网站安全性。
内容的提问来源于stack exchange,提问作者J. O'Ceallacháin
相关产品推荐
相关产品推荐

