使用Cordova时无法显示用户名的技术问题求助
本地通过XAMPP运行代码时,可正常访问服务器并显示用户名;但通过Cordova运行时,无法读取登录时存储在$_SESSION中的用户名,抛出「Warning: Undefined array key "username"」错误。已确认Cordova可正常访问服务器(应用帖子能正常展示),HTML页面通过onload调用displayUserName()向displayName.php发起请求,displayAllPosts()功能正常。
相关代码
登录逻辑(login.php)
<?php session_start(); // Establish connection to database include("connection.php"); header('Access-Control-Allow-Origin: *'); //header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS'); //header('Access-Control-Allow-Headers: Content-Type'); $email = $_POST['email']; $password = $_POST['password']; $sql_user = "SELECT username, user_id FROM users WHERE email = '$email' AND password = '$password'"; $result_user = mysqli_query($link, $sql_user) or die (mysqli_connect($link)); if ((mysqli_num_rows($result_user) < 1)){ echo 1; }else{ $row = mysqli_fetch_array($result_user); $_SESSION['username'] = $row['username']; $_SESSION['user_id'] = $row['user_id']; echo 2; } $conn->close(); ?>
获取用户名(displayName.php)
<?php session_start(); include("connection.php"); header('Access-Control-Allow-Origin: *'); echo $_SESSION['username']; ?>
前端JS代码片段
function displayUserName() { $.ajax({ url: 'http://MY_IP_ADDRESS/test/server/displayName.php', type: 'GET', data: {}, success: function (userdata) { if (!userdata) { document.getElementById("displayname").innerHTML = "No text"; }else { document.getElementById("displayname").innerHTML = "Inloggad: " + userdata; } } }); }; function displayAllPosts() { $.ajax({ url: 'http://MY_IP_ADDRESS/test/server/displayAllPosts.php', type: 'GET', data: {}, dataType: "json", success: function (data) { if (!data) { document.getElementById("displayAllPosts").innerHTML = "no data."; }else { const allPosts = document.getElementById('displayAllPosts');
前端HTML片段
<body onload="displayUserName(); displayAllPosts()"> <div class="container pt-3 pb-3"> <div class="row"> <div class="justify-content-center"> <img src="img/hth.png" alt="Here to help logo" width="300" height="100"> </div> </div> </div> <div class="container pt-3 pb-1"> <div class="row"> <div class="col d-flex justify-content-end" id="displayname"></div> </div> </div> <div class="container pt-1 pb-3"> <div class="row"> <div class="col d-flex justify-content-center"> <h1>Inlägg</h1> </div> </div> </div> <div class="container pt-1 pb-3"> <div class="row"> <div class="event-wrapper" id="displayAllPosts"></div> </div> </div>
问题根源
PHP的$_SESSION依赖Cookie传递会话ID(PHPSESSID):
- 本地XAMPP运行时属于同域请求,浏览器会自动携带Cookie,服务器能识别会话,所以正常读取
$_SESSION。 - Cordova是跨域请求服务器,默认AJAX不会携带Cookie;同时代码设置了
Access-Control-Allow-Origin: *,这种情况下浏览器会禁止携带凭证(Cookie),导致服务器无法识别会话,自然读不到$_SESSION['username']。
解决方案
1. 修正服务器端CORS配置
将login.php和displayName.php的CORS头修改为允许带凭证的格式,不能用*作为源:
// 替换原Access-Control-Allow-Origin头 header('Access-Control-Allow-Origin: file://'); header('Access-Control-Allow-Credentials: true'); header('Access-Control-Allow-Methods: GET, POST, OPTIONS'); header('Access-Control-Allow-Headers: Content-Type');
注:Android 9+需在
config.xml中添加服务器域名的允许规则,避免网络安全限制:<access origin="http://MY_IP_ADDRESS/test/*" />
2. 前端AJAX开启凭证携带
在displayUserName()和登录请求的AJAX中添加xhrFields: { withCredentials: true },确保Cookie被携带:
function displayUserName() { $.ajax({ url: 'http://MY_IP_ADDRESS/test/server/displayName.php', type: 'GET', xhrFields: { withCredentials: true }, // 新增此行 data: {}, success: function (userdata) { if (!userdata) { document.getElementById("displayname").innerHTML = "No text"; }else { document.getElementById("displayname").innerHTML = "Inloggad: " + userdata; } } }); };
登录请求的AJAX也要添加同样配置,确保服务器设置的PHPSESSID Cookie被Cordova保存并在后续请求中携带。
3. 可选:改用JWT令牌替代Session(更适配跨端)
如果Session+Cookies方案仍有兼容性问题,推荐使用JWT:
- 登录成功后,服务器生成包含用户信息的JWT令牌返回前端
- 前端将令牌存在
localStorage中 - 后续请求在头中添加
Authorization: Bearer <令牌> - 服务器验证令牌有效性后返回数据
这种方案不依赖Cookie,更适合跨平台应用。
4. 修复登录代码的SQL注入风险(必做)
当前登录代码直接拼接用户输入,存在严重SQL注入风险,必须改用预处理语句:
// 替换原SQL查询部分 $stmt = $link->prepare("SELECT username, user_id FROM users WHERE email = ? AND password = ?"); $stmt->bind_param("ss", $email, $password); $stmt->execute(); $result_user = $stmt->get_result(); if ($result_user->num_rows < 1) { echo 1; } else { $row = $result_user->fetch_assoc(); $_SESSION['username'] = $row['username']; $_SESSION['user_id'] = $row['user_id']; echo 2; } $stmt->close();
同时,密码不能明文存储,需用password_hash()加密,登录时用password_verify()验证。
内容的提问来源于stack exchange,提问作者sirdeschan

