You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SESSION变量刷新后值异常,移动端导航栏加载错误求助

视口识别导航加载异常问题排查

我正在开发一个视口识别功能,逻辑如下:用户首次访问网站时,通过检测屏幕宽度判断设备类型(≤768px为移动端,否则为PC端),将数据存入带隐藏输入框的表单,再通过fetch把FormData提交到PHP文件。PHP文件需要完成:

  • 通过POST获取表单数据
  • 处理首次加载标识与移动端标识数据
  • 将数据存入SESSION变量
  • 转换为JSON格式返回

前端JS接收JSON后设置对应文本框的值,但目前导航栏出现异常:首次加载无导航栏,刷新后无论设备类型均显示移动端导航栏。


相关代码

前端代码

<?php
  session_start();
?>
<script>
  window.addEventListener("load", async function(){
    if (typeof isMobileJSVar == "undefined" || isMobileJSVar == null){
      function determineIfIsMobile(){
      let screenWidth = screen.width;
      let isMobileDevice;
      //避免重复提交表单弹窗
        if ( window.history.replaceState ) {
          window.history.replaceState( null, null, window.location.href );
        }
        //判断视口宽度
        switch(screenWidth){
          case (screenWidth <= 768)   : isMobileDevice = true;
          return isMobileDevice;
          break;
          case (screenWidth > 768)    : isMobileDevice = false;
          return isMobileDevice;
          break;
          default                     : isMobileDevice = false;
          return isMobileDevice;
          break;
        }
    }
    //初始化元素
    let isSubmitted = false;
    let isMobileHelperURL = "./wp-content/themes/almondotheme/template_parts/outsourcedPHP/isMobileHelper.php";
    let isMobileMiddleManTextElement = document.getElementById("isMobileMiddleManText");
    let isFirstLoadHelperELement = document.getElementById("isFirstLoadHelper");
    let mobileMiddleManFormElement = document.getElementById("mobileMiddleManForm");
    let isUserMobile = determineIfIsMobile();
    //通过Fetch与PHP通信
    function isMobile(){
      isMobileMiddleManTextElement.value = isUserMobile;
      fetch(isMobileHelperURL,{
        method: 'POST',
        body: new FormData(document.getElementById('mobileMiddleManForm')),
      })
        .then(returnedisMobileJSON=>{
          return returnedisMobileJSON.json();
        })
        .then(parsedisMobileJSON=>{
          
          var setHelperInputsFunction= function() {
            document.getElementById("isFirstLoadHelper").value = parsedisMobileJSON.isFirstLoad;
            document.getElementById("isMobileMiddleManText").value = parsedisMobileJSON.isMobile;
          }()
        })


        let isFirstLoadJSVar = document.getElementById("isFirstLoadHelper").value;
        let isMobileJSVar = document.getElementById("isMobileMiddleManText").value;
        alert(isMobileJSVar);
      };
      isMobile();
    }

  })
</script>

PHP处理文件代码

<?php
session_start();
$isMobileArray = array();
if(isset($_SESSION["isFirstLoad"])){
    $_SESSION["isFirstLoad"] = false;
    $isMobileArray["isFirstLoad"] = $_SESSION["isFirstLoad"];
}
else{
    $_SESSION["isFirstLoad"] = true;
    $isMobileArray["isFirstLoad"] = $_SESSION["isFirstLoad"];
}


if(!(isset($isMobileArray["isMobile"]))){
    $_SESSION["isMobile"] = $_POST["isMobileMiddleManText"];
    $isMobileArray["isMobile"] = $_POST["isMobileMiddleManText"];
    
}
else{
    $_SESSION["isMobile"] = $_POST["isMobileMiddleManText"];
    $isMobileArray["isMobile"] = $_POST["isMobileMiddleManText"];
}



$JSONToReturn = json_encode($isMobileArray);

echo $JSONToReturn;

?>

导航栏代码

<?php
    //检查是否为移动设备
    if(isset($_SESSION["isMobile"])){
        if ($_SESSION["isMobile"] == true){
            get_template_part("./template_parts/navigation_mobile");
        }
        else{
            get_template_part("./template_parts/navbar_pc.php");
        }
    }
    else{
        get_template_part("./template_parts/navbar_pc.php");
    }
  
?>

问题根源与修复方案

1. 前端设备判断逻辑错误

原代码用switch做范围判断是错误的(switch是严格值匹配,不是条件判断),导致永远走default分支返回false。替换为if-else:

function determineIfIsMobile(){
  let screenWidth = screen.width;
  //避免重复提交表单弹窗
  if ( window.history.replaceState ) {
    window.history.replaceState( null, null, window.location.href );
  }
  return screenWidth <= 768;
}

2. PHP类型比较逻辑错误

PHP中字符串"false"与true用==比较时会被转换为布尔值true(非空字符串均为true),导致无论提交什么值都加载移动端导航。修复方式:

  • 转换POST值为布尔类型再存入SESSION
  • 用严格比较===判断值

修改PHP处理文件:

<?php
session_start();
$isMobileArray = [];

//处理首次加载标识
if(isset($_SESSION["isFirstLoad"])){
    $_SESSION["isFirstLoad"] = false;
} else {
    $_SESSION["isFirstLoad"] = true;
}
$isMobileArray["isFirstLoad"] = $_SESSION["isFirstLoad"];

//处理移动端标识:转换为布尔类型
$isMobile = filter_input(INPUT_POST, 'isMobileMiddleManText', FILTER_VALIDATE_BOOLEAN);
$_SESSION["isMobile"] = $isMobile;
$isMobileArray["isMobile"] = $isMobile;

echo json_encode($isMobileArray);
?>

修改导航栏代码的判断:

if ($_SESSION["isMobile"] === true){
    get_template_part("./template_parts/navigation_mobile");
}

3. 前端异步回调的变量赋值问题

原代码中isFirstLoadJSVar和isMobileJSVar在fetch回调外定义,此时请求未完成,无法获取最新值,需移至回调内部:

function isMobile(){
  isMobileMiddleManTextElement.value = isUserMobile;
  fetch(isMobileHelperURL,{
    method: 'POST',
    body: new FormData(document.getElementById('mobileMiddleManForm')),
  })
    .then(returnedisMobileJSON => returnedisMobileJSON.json())
    .then(parsedisMobileJSON => {
      document.getElementById("isFirstLoadHelper").value = parsedisMobileJSON.isFirstLoad;
      document.getElementById("isMobileMiddleManText").value = parsedisMobileJSON.isMobile;
      
      //变量赋值移至回调内,确保拿到最新值
      let isFirstLoadJSVar = document.getElementById("isFirstLoadHelper").value;
      let isMobileJSVar = document.getElementById("isMobileMiddleManText").value;
      alert(isMobileJSVar);
    })
};

4. 首次加载SESSION未设置问题

前端fetch是异步操作,首次页面渲染时SESSION还未被设置,可通过两种方式优化:

  • 用PHP的$_SERVER['HTTP_USER_AGENT']做设备判断作为兜底,首次加载直接渲染对应导航
  • 前端页面加载后先通过JS动态渲染导航,再通过fetch更新SESSION供后续刷新使用

内容的提问来源于stack exchange,提问作者Alwin Schneider

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 10:30:42