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

AJAX+CodeIgniter聊天应用仅能发一次消息,后续请求变GET的问题求助

聊天应用AJAX POST请求仅能生效一次的问题

我正在用AJAX+PHP(phpMyAdmin管理数据库)开发聊天应用,当前遇到的问题是:AJAX发送消息的代码仅能正常运行一次,之后无法插入新消息。第一次请求能正常工作,但后续发送消息时,浏览器不再使用AJAX的POST方法,而是改用GET方法。已确认控制器和方法(Chat/acceptMessage)调用正确,该方法会调用PorukaModel的插入函数。


前端AJAX代码

function sendMessage() {
    const message = messageInput.val();
    if (message === "") return;
    let url = new URL(window.location.href);
    let params = new URLSearchParams(url.search);
    let IdFrom = params.get("IdFrom");
    let IdTo = params.get("IdTo");
    
    // 创建新URL
    let urlParts = url.href.split('/');
    urlParts.pop();
    urlParts.pop();
    urlParts.push("Chat");
    urlParts.push("acceptMessage");
    let newUrl = urlParts.join('/');  
    
    $.ajax({
      url: newUrl,
      method: "POST",
      data: {
        message: message,
        from: IdFrom,
        to: IdTo,
      },
      success: function (response) {
        // 假设服务器返回发送的消息
        appendMessage("Server", response);
        messageInput.val(""); // 清空输入框
        messageInput.focus(); // 重新聚焦输入框
      },
      error: function (error) {
        // 处理错误
        console.log("Error:", error);
      },
    });    
    return false;
  }

PorukaModel代码

<?php

namespace App\Models;

use CodeIgniter\Model;

/**
 * PorukaModel - 实现数据库表操作功能的类
 * 
 * @version 1.0
 */
class PorukaModel extends Model
{
    /**
     * var String $table
     */
    protected $table      = "poruka";
    /**
     * var String $primaryKey
     */
    protected $primaryKey = "IdP";
    /**
     * var String $returnType
     */
    protected $returnType     = "object";
    /**
     * var Array $allowedFields
     */
    protected $allowedFields = ["Tekst", "DatumVreme", "IdPri", "IdPos"];

    public function insertData($IdFrom, $IdTo, $message)
    {
        $data = array(
            'IdPri' => $IdTo,
            'IdPos' => $IdFrom,
            'Tekst' => $message,
            'DatumVreme' => date('Y-m-d H:i:s'),
        );
        $this->insert($data, true); // true 表示自动验证
    }

}

?>

Chat控制器代码

<?php

namespace App\Controllers;

use App\Models\PorukaModel;

class Chat extends BaseController
{
    /**
     * 显示用户首页
     * 
     * @return Response
     */
    public function showChatting()
    {
        $this->show("cetovanje", []);
    }

    // 是否需要同步
    public function acceptMessage(){
        $message = isset($_POST['message']) ? $_POST['message'] : null;
        $IdTo = isset($_POST['from']) ? intval($_POST['from']) : null;
        $IdFrom = isset($_POST['to']) ? intval($_POST['to']) : null;
        $PorukaModel = new PorukaModel(); 
        $PorukaModel->insertData($IdFrom, $IdTo, $message);

        // $response = "Message received: ".$message;
        // echo $response;
    }
}

?>

问题排查与解决方案

1. 控制器未返回响应导致请求异常

当前acceptMessage方法没有返回任何响应,AJAX请求完成后无法正确处理后续逻辑,可能导致浏览器请求行为异常。需要在方法末尾添加响应输出:

public function acceptMessage(){
    $message = isset($_POST['message']) ? $_POST['message'] : null;
    $IdTo = isset($_POST['from']) ? intval($_POST['from']) : null;
    $IdFrom = isset($_POST['to']) ? intval($_POST['to']) : null;
    
    if($message && $IdTo && $IdFrom){
        $PorukaModel = new PorukaModel(); 
        if($PorukaModel->insertData($IdFrom, $IdTo, $message)){
            echo json_encode(['status' => 'success', 'message' => $message]);
        } else {
            echo json_encode(['status' => 'error', 'msg' => '消息插入失败']);
        }
    } else {
        echo json_encode(['status' => 'error', 'msg' => '参数缺失']);
    }
}

同时修改AJAX的success回调,处理JSON格式响应:

success: function (response) {
    let res = JSON.parse(response);
    if(res.status === 'success'){
        appendMessage("Server", res.message);
        messageInput.val("");
        messageInput.focus();
    } else {
        console.log("错误:", res.msg);
    }
},

2. 修复URL拼接的潜在问题

当前通过拆分URL拼接新地址的方式容易出错,建议直接使用CodeIgniter的URL辅助函数生成正确接口地址。在前端页面中预先定义:

<script>
const acceptMessageUrl = "<?= base_url('Chat/acceptMessage') ?>";
</script>

然后在AJAX中直接使用:

$.ajax({
  url: acceptMessageUrl,
  // ...其他参数
});

3. 阻止默认表单提交行为

如果sendMessage函数绑定在表单的提交事件上,确保彻底阻止默认表单提交,避免GET请求覆盖AJAX的POST请求:

function sendMessage(event) {
    event.preventDefault(); // 添加这行
    const message = messageInput.val();
    // ...后续代码
}

4. 禁用AJAX缓存

添加cache: false参数,避免浏览器缓存请求导致的异常:

$.ajax({
  url: acceptMessageUrl,
  method: "POST",
  cache: false,
  // ...其他参数
});

5. 增强模型插入的可靠性

在insertData方法中返回插入结果,便于控制器判断操作是否成功:

public function insertData($IdFrom, $IdTo, $message)
{
    $data = array(
        'IdPri' => $IdTo,
        'IdPos' => $IdFrom,
        'Tekst' => $message,
        'DatumVreme' => date('Y-m-d H:i:s'),
    );
    return $this->insert($data, true); // 返回插入结果
}

内容的提问来源于stack exchange,提问作者Nikola Nikolic

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 12:52:00