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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 22:37:31