在SO上有几个这样的问题,但没有一个答案对我有用。我试过了所有这些。
我试图最小化我粘贴的代码,但这个脚本很难
我有一个评论表单,通过ajax提交给php脚本,该脚本保存评论,然后获取所有评论并重新显示它们,以便在不刷新页面的情况下显示新评论。
有时评论会成功提交到数据库并正确重新显示。 通常几乎每隔一次提交评论都会被保存。每隔一段时间似乎都没有发生。
我真正的问题是每次提交时都不会保存评论。
这是javascript和ajax调用:
$(document).ready(function(){
var working = false;
$('#commentForm').submit(function(e){
if(working) return false;
working = true;
$('#submitComment').val('Working..');
$('span.error').remove();
$.post('/ajax/comment.process.php',$(this).serialize(),function(msg){
working = false;
$('#submitComment').val('Submit');
if(msg.status){
$('#commentArea').slideDown().$(msg.html).prepend('#commentArea');
$('#blogComment').val('');
}
else {
$.each(msg.errors,function(k,v){
$('label[for='+k+']').append('<span class="error">'+v+'</span>');
});
}
},'json');
});
});
这是提交评论的功能:
public function addComment($user_id) {
$validate = new data_validation;
$_POST = $validate->sanitize($_POST);
$newCom = $_POST['blogComment'];
$blog_id = intval($_POST['blogID']);
$photoSubmit = $_POST['comPhoto'];
$newComQuery = $this->mysqli->query("INSERT INTO b_comments (blog_id, user_id, date, content, photo) VALUES ('".$blog_id."', '".$user_id."', Now(), '".$newCom."', '".$photoSubmit."')");
if($newComQuery === false) {
echo "Query failed";
}else{
$returnCom = $this->comMarkup($blog_id);
echo $returnCom;
}
}
这里是comMarkup()
函数的一部分,它回应了评论(它只是重要部分):
// This method outputs the XHTML markup of the comment
public function comMarkup($blog_id) {
$sql = $this->mysqli->query("SELECT * FROM b_comments WHERE blog_id = '".$blog_id."' ORDER BY date DESC");
while($d = $sql->fetch_assoc()) {
$d = $validate->sanitize($d);
echo "
<div class='comment-block'>
<span class='com-img'><img src='".$photo_path."' /></span>
<h3 style='display: inline;'><a href='".$profile."'>".$userName."</a></h3>
<div class='com-date'>".$d['date']."</div>
<p>".$comContent."</p>
</div>
";
}
}
编辑:以下是所请求的comment.process.php代码:
session_start();
include_once('../classes/comment.class.php');
include_once('../classes/db.class.php');
include_once('../classes/user.class.php');
$user_id = $_SESSION['user_id'];
$db = new DBConnection;
$comments = new Comment($db);
$user = new User($db);
$blogID = intval($_POST['blogID']);
$addCom = $comments->addComment($user_id);
echo json_encode(array('status'=>1,'html'=>$addCom));
答案 0 :(得分:1)
根据您的说明,我的猜测是,它与您的working
变量有关,而且它在false
的末尾没有设置为$.post()
。
但是,您制定流程的方式存在一些逻辑,效率和可管理性问题。我建议您查看official jQuery docs for $.post(),特别是.done()
,.fail()
和.always()
链式方法。
我还建议将PHP变量命名为$_POST
之外的其他内容,这样就不会与PHP超级全局混淆。
最后,我建议将您的评论视为对象并使用PDO(这是指向PDO的链接:查询作为一种&#34;沉浸式&#34;方法但请务必阅读所有文档)。它将为您节省大量数据库交互的麻烦。
答案 1 :(得分:1)
看起来你有working
标志引起的竞争条件。由于您只是使用该标志来显示“正在工作...”消息并在请求处理时阻止提交,我将使用正常的$.ajax
调用并将“工作”逻辑放在{{ 1}}选项。这是一个例子:
beforeSend
答案 2 :(得分:0)
答案 3 :(得分:0)
我猜你应该使用encodeURIComponent($('#blogComment').val())
somwhere将你的blogcomment值传递给PHP文件进行插入。
编辑1:
public function addComment($user_id) {
$validate = new data_validation;
$_POST = $validate->sanitize($_POST);
$newCom = rawurlencode($_POST['blogComment']);
如果rawurlencode()
不起作用。使用以下功能:
function encodeURIComponentNew($str) {
$revert = array('%21'=>'!', '%2A'=>'*', '%27'=>"'", '%28'=>'(', '%29'=>')');
return strtr(rawurlencode($str), $revert);
}
(来自What is the equivalent of JavaScript's encodeURIcomponent in PHP?的功能)
然后
public function addComment($user_id) {
$validate = new data_validation;
$_POST = $validate->sanitize($_POST);
$newCom = encodeURIComponentNew($_POST['blogComment']);
答案 4 :(得分:0)
怀疑这是相关的,但是在过去使用函数内部使用“echo”执行ajax的东西,然后尝试再次回显返回的值时,我遇到了一些问题。
尝试在“返回”中更改所有函数内部的echo,如下所示:
public function addComment($user_id) {
$validate = new data_validation;
$_POST = $validate->sanitize($_POST);
$newCom = $_POST['blogComment'];
$blog_id = intval($_POST['blogID']);
$photoSubmit = $_POST['comPhoto'];
$newComQuery = $this->mysqli->query("INSERT INTO b_comments (blog_id, user_id, date, content, photo) VALUES ('".$blog_id."', '".$user_id."', Now(), '".$newCom."', '".$photoSubmit."')");
if($newComQuery === false) {
return "Query failed";
}else{
$returnCom = $this->comMarkup($blog_id);
return $returnCom;
}
}
答案 5 :(得分:0)
如果用户使用'
发送评论,则可能会发生错误。发送注释时,该字符串将破坏mmysqli_query。它可以帮助你,可能。
public function addComment($ user_id){
$validate = new data_validation;
$_POST = $validate->sanitize($_POST);
$newCom = htmlspecialchars($_POST['blogComment'], ENT_QUOTES);
$blog_id = intval($_POST['blogID']);
$photoSubmit = htmlspecialchars($_POST['comPhoto'], ENT_QUOTES);
$newComQuery = $this->mysqli->query("INSERT INTO b_comments (blog_id, user_id, date, content, photo) VALUES ('".$blog_id."', '".$user_id."', Now(), '".$newCom."', '".$photoSubmit."')");
if($newComQuery === false) {
echo "Query failed";
}else{
$returnCom = $this->comMarkup($blog_id);
echo $returnCom;
}
}
答案 6 :(得分:0)
可能会导致浏览器Cookie 。因此,在网址中,只需为唯一网址格式添加其他查询字符串。
示例:强>
$.post('/ajax/comment.process.php?random=randamnumber');
答案 7 :(得分:0)
因此,如果我正确理解了问题,您就会提交评论并且没有插入数据库,并且它的也可能不会向您展示数据库错误或打印出Query failed
字符串?
好像你的PHP脚本根本没有被执行?
如果是这种情况,我通常会说最容易发生间歇性错误的罪魁祸首,例如这是您的浏览器缓存。您的浏览器正在查看URL,认为它已经知道该URL的内容是什么,并返回该内容,甚至没有将您的信息发送到服务器。最简单的方法是在文件调用中添加一个随机查询字符串,例如:
cachebuster = new Date();
'/ajax/comment.process.php?cachebuster='.cachebuster.getTime();
...我说&#34;通常&#34;因为你正在使用POST并且正常&#34;正常&#34;情况下,浏览器不会缓存POST请求。但这是可能的,并且打击是微不足道的,所以试一试。这也可以诊断,如果你使用Chrome,点击f12,进入&#34;网络&#34;选项卡,然后运行您的表单。它应告诉您是否从缓存中检索到结果。
除此之外,如果你依赖magic_quotes(或者更糟糕的是,你 依赖magic_quotes),你需要学习处理SQL注入的正确方法。您永远不应该将不受信任的数据从浏览器直接插入数据库。转义它或使用参数化查询。如果您的查询出现间歇性问题,则可能与您在某些情况下抛弃查询的评论内容有关,如上所述,最有可能是收缩中包含撇号。通过连续提交两个表单进行诊断:trythis
然后try'this
。如果第一个失败了,第二个失败了,你很可能找到了答案。正确地逃避你的输入将解决这个问题。
最终,所有这些建议都已在上面给出,但希望这提供了一些背景来帮助理解为什么和为什么会这样做。
编辑:我知道,现在我看起来更接近了,你实际上是用你在这里分享的方法来逃避你的查询。假设它正常工作,那么就不应该成为一个问题。
尝试在脚本开头回显一个有效的响应,甚至不执行任何操作。如果它总是返回,那么你至少知道脚本被成功调用。
如果ajax调用返回错误,可能成为working
变量的问题。在这种情况下,它永远不会让它回归假。
你的#1盟友是&#34;网络&#34; Chrome开发者工具中的标签或在Firefox Firebug扩展程序的控制台标签中观看响应。
编辑2:
$.post('/ajax/comment.process.php',$(this).serialize(),function(msg){
// post stuff, REMOVING the working variable set, cuz it won't be necessary here...
},'json').always(function() { working = false; });
答案 8 :(得分:0)
您的PHP代码中存在SQL注入漏洞,请确保正确转义变量或使用准备好的查询。
对于JS部分,请确保返回true;在.submit()函数的末尾。 (对你而言,它将在$ .post()调用之后)
此外,如果您的php脚本中存在错误,那么您的'working'变量可以永久设置为true,这对于SQL Injection Vuln来说非常可能。
解释:您将其设置为true,由于PHP Backend的错误500,可能无法调用成功回调,因此回调中永远不会将其设置为false,然后你不能再提交,直到下一页刷新。