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
相关产品推荐
相关产品推荐

