创建一个基于 AJAX 的聊天系统。如何避免提交内容的页面刷新并实时显示新消息
Creating an AJAX based chat system. How to avoid page refresh on submitted content and show new messages live
我正在尝试在 PhP 上制作一个简单的聊天系统。
我的想法真的很简单,我有一个表单,可以将文本发送到 PHP 中的脚本,该脚本将 var 保存在数据库中,然后其他用户刷新页面以下载新消息并将其显示在聊天框。
问题来了,当我说刷新页面时。
我只是认为这对于用户每秒或更短时间刷新整个页面可能是一个问题,感谢 JavaScript 功能。
最初的想法是使用 setInterval()
但我知道我认为这可能是个坏主意。
我不确定,但是从 chrome 开始,当您刷新表单时,它会保存表单并自动填写,一旦您完成刷新,每个浏览器都会这样做吗?
Willa 用于刷新页面的 JavaScript 功能对于连接速度非常慢的人来说是个问题吗?
但最重要的是,要解决这个问题,实际上可以只刷新特定的 PHP 脚本,让用户只刷新该脚本并下载新消息,而不是每秒刷新整个页面?
所有帮助将不胜感激。
-注意-
老实说,要我做那个聊天系统的人让我不要使用JavaScript,所以理论上我什至不允许使用setInterval()
使用名为 load() 的 jQuery 函数。 Post 聊天页面的基本 HTML 标记,我将编辑一个具体的答案。
$("#messageboard").load("chat.php #messageboard > *");
在聊天提交后将此代码放入您的 ajax 保存请求中。修改#messageboard为需要刷新的留言板IDdiv。将 chat.php 更改为显示聊天的页面。为了节省加载时间,您可以将 GET vars 传递到聊天页面并防止页面完全加载,return 仅加载消息。
您也可以使用 setTimeout 函数,但两者都需要在页面上 运行 以便提交消息的用户立即看到刷新(无滞后)
function startTimer() {
$("#messageboard").load("chat.php #messageboard > *", function(){
//repeats itself after 1 seconds
setTimeout(startTimer, 1000);
});
}
startTimer();
上面1000是毫秒所以等于1秒
使用 setTimeout 的好处是,如果连接挂起一段时间,您将不会收到大量待处理的请求,因为只有在前一个请求完成后才会发送新的请求。
我假设您正在使用 ajax 提交用户消息,因此每次用户发布内容时页面不会刷新。需要一个例子吗?
<html>
<head>
<script
src="https://code.jquery.com/jquery-2.2.4.min.js"
integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="
crossorigin="anonymous"></script>
<script>
$('document').ready(function(){
$('#submit').click(function(){
var message = $('#message').val();
$('#message').reset();
$.post('chat.php',{message: message},function(response){
$("#messageboard").load("chat.php #messageboard > *");
});
})
$('#message').keypress(function(e){
if(e.which == 13){//Enter key pressed
var message = $('#message').val();
$('#message').reset();
$.post('chat.php',{message: message},function(response){
$("#messageboard").load("chat.php #messageboard > *");
});
}
});
function startTimer() {
$("#messageboard").load("chat.php #messageboard > *", function(){
//repeats itself after 1 seconds
setTimeout(startTimer, 1000);
});
}
startTimer();
});
</script>
</head>
<body>
<div id="messageboard"></div>
<input type="text" placeholder="Message" id="message"><input value="submit" type="button" id="submit">
</body>
</html>
上面的代码会在提交按钮上触发 POST,但如果用户按下回车键也会触发。该脚本将自动刷新,但也会在新的输入提交时刷新。这只是一个概念。确保创建服务器端处理程序以将消息保存到数据库。
如果您只想使用服务器端的 php,您可以使用 php 缓存来避免刷新页面并处理位于服务器上的文件中的消息。
例如,您可以在 while 循环中检查一些文件内容,然后显示然后擦除它直到超时。提交表单可以使用 php 将数据写入文件。如果你愿意,你可以制作 XML ,但这是一种原始的方法:
在浏览器中显示/刷新数据的文件:
testChat.php
<?php
$timeout=200;
set_time_limit($timeout+1);//Maximum execution time.
flushBrowser();//Print space chars to have cache flush on browsers.
$str='';
while ($timeout>0){
//Flush data to display
ob_flush();
flush();
if ($str!=checkPostMsgQueued())
echo checkPostMsgQueued()."\n";
$str=checkPostMsgQueued();
//wait...
sleep(1);
$timeout-=1;
}
ob_end_flush();
//Many browsers seems to receive some data before flushing.
function flushBrowser(){
if (ob_get_level() == 0) ob_start();
echo str_pad('',4096)."\n";
}
function checkPostMsgQueued(){
$filename="testChat.txt";
if (file_exists($filename)){
$stream=fopen($filename, 'r');
$str=stream_get_line($stream,128);
fclose($stream);
}
return $str;
}
testchatsubmit.php :
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<form action="testChatSubmit.php" method="post">
<input type="text" name="message" id="message">
<input type="submit" name="submit">
</form>
</body>
</html>
<?php
if (isset($_POST['message'])){
$fp = fopen('testChat.txt', 'w');
fwrite($fp, $_POST['message']);
fclose($fp);
}
?>
顺便说一句,正如我所说,这样做可能有点苛刻......
我认为您别无选择,只能使用一些客户端语言在同一页面上显示和 post 数据 :)
祝你好运!
编辑:
这是实现它的方法:
制作另一个 html 文件,其中包含 2 个 iframe:
testchatframes.html :
<iframe src="testchat.php"></iframe>
<iframe src="testchatsubmit.php"></iframe>
我还修改了初始 testChat.php 代码的一些块,使其在多个 "clients" 上工作(我在本地主机上试过),使用流而不是粗暴地删除行......我不不认为这是正确的做法(也许您应该注意到 "the guy who want you to do that"),但这非常有趣且有效!它甚至似乎没有那么昂贵的资源...:)干杯!
对于刷新部分,您可以使用 <META http-equiv="refresh" content="3; URL=truc.php">
而不是 setInterval(顺便说一句,setTimeout 就足够了,因为它会在每次页面刷新时发生 1 次)。
对于表单填写,当你提交消息时它会刷新页面并释放表单,这样就可以了。对于刚刚 "read" 的人,如果他开始输入内容并且页面刷新,它应该在刷新后保留它,这样 il 看起来也不错吗?但是您可以添加 autocomplete="off"
以确保表单不会建议任何不需要的内容。
我正在尝试在 PhP 上制作一个简单的聊天系统。
我的想法真的很简单,我有一个表单,可以将文本发送到 PHP 中的脚本,该脚本将 var 保存在数据库中,然后其他用户刷新页面以下载新消息并将其显示在聊天框。
问题来了,当我说刷新页面时。
我只是认为这对于用户每秒或更短时间刷新整个页面可能是一个问题,感谢 JavaScript 功能。
最初的想法是使用 setInterval()
但我知道我认为这可能是个坏主意。
我不确定,但是从 chrome 开始,当您刷新表单时,它会保存表单并自动填写,一旦您完成刷新,每个浏览器都会这样做吗?
Willa 用于刷新页面的 JavaScript 功能对于连接速度非常慢的人来说是个问题吗?
但最重要的是,要解决这个问题,实际上可以只刷新特定的 PHP 脚本,让用户只刷新该脚本并下载新消息,而不是每秒刷新整个页面?
所有帮助将不胜感激。
-注意-
老实说,要我做那个聊天系统的人让我不要使用JavaScript,所以理论上我什至不允许使用setInterval()
使用名为 load() 的 jQuery 函数。 Post 聊天页面的基本 HTML 标记,我将编辑一个具体的答案。
$("#messageboard").load("chat.php #messageboard > *");
在聊天提交后将此代码放入您的 ajax 保存请求中。修改#messageboard为需要刷新的留言板IDdiv。将 chat.php 更改为显示聊天的页面。为了节省加载时间,您可以将 GET vars 传递到聊天页面并防止页面完全加载,return 仅加载消息。
您也可以使用 setTimeout 函数,但两者都需要在页面上 运行 以便提交消息的用户立即看到刷新(无滞后)
function startTimer() {
$("#messageboard").load("chat.php #messageboard > *", function(){
//repeats itself after 1 seconds
setTimeout(startTimer, 1000);
});
}
startTimer();
上面1000是毫秒所以等于1秒
使用 setTimeout 的好处是,如果连接挂起一段时间,您将不会收到大量待处理的请求,因为只有在前一个请求完成后才会发送新的请求。
我假设您正在使用 ajax 提交用户消息,因此每次用户发布内容时页面不会刷新。需要一个例子吗?
<html>
<head>
<script
src="https://code.jquery.com/jquery-2.2.4.min.js"
integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="
crossorigin="anonymous"></script>
<script>
$('document').ready(function(){
$('#submit').click(function(){
var message = $('#message').val();
$('#message').reset();
$.post('chat.php',{message: message},function(response){
$("#messageboard").load("chat.php #messageboard > *");
});
})
$('#message').keypress(function(e){
if(e.which == 13){//Enter key pressed
var message = $('#message').val();
$('#message').reset();
$.post('chat.php',{message: message},function(response){
$("#messageboard").load("chat.php #messageboard > *");
});
}
});
function startTimer() {
$("#messageboard").load("chat.php #messageboard > *", function(){
//repeats itself after 1 seconds
setTimeout(startTimer, 1000);
});
}
startTimer();
});
</script>
</head>
<body>
<div id="messageboard"></div>
<input type="text" placeholder="Message" id="message"><input value="submit" type="button" id="submit">
</body>
</html>
上面的代码会在提交按钮上触发 POST,但如果用户按下回车键也会触发。该脚本将自动刷新,但也会在新的输入提交时刷新。这只是一个概念。确保创建服务器端处理程序以将消息保存到数据库。
如果您只想使用服务器端的 php,您可以使用 php 缓存来避免刷新页面并处理位于服务器上的文件中的消息。 例如,您可以在 while 循环中检查一些文件内容,然后显示然后擦除它直到超时。提交表单可以使用 php 将数据写入文件。如果你愿意,你可以制作 XML ,但这是一种原始的方法: 在浏览器中显示/刷新数据的文件: testChat.php
<?php
$timeout=200;
set_time_limit($timeout+1);//Maximum execution time.
flushBrowser();//Print space chars to have cache flush on browsers.
$str='';
while ($timeout>0){
//Flush data to display
ob_flush();
flush();
if ($str!=checkPostMsgQueued())
echo checkPostMsgQueued()."\n";
$str=checkPostMsgQueued();
//wait...
sleep(1);
$timeout-=1;
}
ob_end_flush();
//Many browsers seems to receive some data before flushing.
function flushBrowser(){
if (ob_get_level() == 0) ob_start();
echo str_pad('',4096)."\n";
}
function checkPostMsgQueued(){
$filename="testChat.txt";
if (file_exists($filename)){
$stream=fopen($filename, 'r');
$str=stream_get_line($stream,128);
fclose($stream);
}
return $str;
}
testchatsubmit.php :
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<form action="testChatSubmit.php" method="post">
<input type="text" name="message" id="message">
<input type="submit" name="submit">
</form>
</body>
</html>
<?php
if (isset($_POST['message'])){
$fp = fopen('testChat.txt', 'w');
fwrite($fp, $_POST['message']);
fclose($fp);
}
?>
顺便说一句,正如我所说,这样做可能有点苛刻......
我认为您别无选择,只能使用一些客户端语言在同一页面上显示和 post 数据 :)
祝你好运!
编辑:
这是实现它的方法:
制作另一个 html 文件,其中包含 2 个 iframe: testchatframes.html :
<iframe src="testchat.php"></iframe>
<iframe src="testchatsubmit.php"></iframe>
我还修改了初始 testChat.php 代码的一些块,使其在多个 "clients" 上工作(我在本地主机上试过),使用流而不是粗暴地删除行......我不不认为这是正确的做法(也许您应该注意到 "the guy who want you to do that"),但这非常有趣且有效!它甚至似乎没有那么昂贵的资源...:)干杯!
对于刷新部分,您可以使用 <META http-equiv="refresh" content="3; URL=truc.php">
而不是 setInterval(顺便说一句,setTimeout 就足够了,因为它会在每次页面刷新时发生 1 次)。
对于表单填写,当你提交消息时它会刷新页面并释放表单,这样就可以了。对于刚刚 "read" 的人,如果他开始输入内容并且页面刷新,它应该在刷新后保留它,这样 il 看起来也不错吗?但是您可以添加 autocomplete="off"
以确保表单不会建议任何不需要的内容。