AJAX请求PHP文件到inser

ajax request to php file to inser

提问人:Blackegg13 提问时间:9/7/2023 最后编辑:BarmarBlackegg13 更新时间:9/12/2023 访问量:63

问:

你能帮我理解为什么我的代码会导致双重插入吗?我有 javascript 函数发出 ajax 请求保存 .php 文件以将数据插入数据库,但每次我提交它都会做两次,但只返回一个 id,不知道第二次插入在哪里进行。

javascript/ajax 函数

function opnActPag () {
    var actDiv = document.getElementById('act_div');
    var actLstCont = document.getElementById('act_lst_cont');
    var actTag = document.getElementById('act_tag');
    var actTxt = document.getElementById('act_txt');
    var actClrTxt = document.getElementById('act_clr_txt');
    var actSubmTxt = document.getElementById('act_subm_txt');
    var actTxtArea = document.getElementById('act_txt_area');
    var actHidVal = document.getElementById('act_hid_val').value;
    var actHidUsr = document.getElementById('act_hid_usr').value;
    actDiv.style.display = 'block';
    opnActPag['closeActPag'] = function () {
        actDiv.style.display = 'none';
        actTxtArea.value = '';
    }
    opnActPag['addAct'] = function () {
        $.ajax({
            type: 'POST',
            url:  'save.php',
            data: { act_txt: actTxtArea.value), id: actHidVal, usr: actHidUsr },
            success : function (data) {
                console.log(data);
            }
        });
    }
    
}

数据来源于

<div class="act-back-drop" id="act_div">
    <div class="act-cont">
        <div class="act-page">
            <div class="act-cls-btn" onclick="opnActPag.closeActPag()">&times;</div>
            <div class="act-list-cont" id="act_lst_cont">
                <!--<div class="act-list-buble"><div class="act-buble-tag" id="act_tag">DATE NAME</div><div class="act-buble-text" id="act_txt">TEXT HOLDER</div></div>-->
            </div>
            <div class="act-text-cont">
                <textarea rows="6" class="act-text-inp" id="act_txt_area"></textarea>
                <input type="hidden" value="" id="act_hid_val">
                <input type="hidden" value="Some user" id="act_hid_usr">
                <div class="act-text-btn-cont">
                    <div class="act-text-btn-no" id="act_clr_txt_" onclick="document.getElementById('act_txt_area_').value = '';">&#215;</div>
                    <div class="act-text-btn-ok" id="act_subm_txt" onclick="opnActPag.addAct()">&#10004;</div>
                    <!--<div class="act-text-btn"></div>-->
                </div>
            </div>
        </div>
    </div>
</div>

保存.php

<?php
if( isset($_POST['act_txt']) && !empty($_POST['act_txt']) ){
    $sql = "select count(*) as count from actions where user_name = '".$_POST['usr']."' and info = '".preg_replace( "/[\r\n]+/", " ",htmlentities(trim($_POST['act_txt']), ENT_QUOTES))."' and level_3_id =".$_POST['id'].";";
    $ret = poke_db($sql,0,1);
    if( $ret[0]['count'] == 0 ){
        $sql = "insert into actions (user_name,info,level_3_id) values('".$_POST['usr']."','".preg_replace( "/[\r\n]+/", " ",htmlentities(trim($_POST['act_txt']), ENT_QUOTES))."','".$_POST['id']."');";
        $ret = poke_db($sql,0,0);
    }
    echo $ret;
}
?>

PHP DB 连接函数

$srv = "localhost";
$usr = "root";
$pas = "pass";
$db_name = "dbname";
function poke_db($sql,$multi,$array){
    global $db_name;
    global $srv;
    global $usr;
    global $pas;
    $servername = $srv;
    $username = $usr;
    $password = $pas;
    $dbname = $db_name;
    $conn = mysqli_init();
    $conn->options(MYSQLI_OPT_CONNECT_TIMEOUT, 5);
    $conn->real_connect($servername, $username, $password, $dbname);
    if ($conn->connect_error) {
        die('[ERR] '.$conn->connect_error);
    }
    if( !$conn -> query($sql) ){
        die('[ERR] ' . $conn -> error);
    }
    if( $multi == 1 ){
        $result = mysqli_multi_query($conn, $sql);
    }else{
        $result = mysqli_query($conn, $sql);
        $id = mysqli_insert_id($conn);
    }
    if( $array == 1 ){
        if( mysqli_num_rows($result) != 0 ){
            $i=0;
            while($row = mysqli_fetch_assoc($result)){
                $out_array[$i] = $row;
                ++$i;
            }
        }else{
            $out_array = null;
        }
        return $out_array;
    }else{
        if( isset($id) ){
            return $id;
        }
    }
}

谢谢

javascript php mysql ajax mariadb

评论

1赞 icecub 9/7/2023
我的第一个猜测是你没有在表单提交中使用,导致你的表单提交,而你的 Ajax 提交(因此重复输入)event.preventDefault()
1赞 Barmar 9/7/2023
仅供参考,您不需要两者和. 检查它是否是自动设置的。isset()!empty()empty()
0赞 Barmar 9/7/2023
@icecub我在想同样的事情,但 HTML 中没有表单或提交按钮。
2赞 Barmar 9/7/2023
检查 DevTools 的“网络”选项卡,查看是否对服务器进行多次调用。使用 XHR 断点查看呼叫的来源。
6赞 Barmar 9/7/2023
您的脚本容易受到 SQL 注入攻击。即使你逃避变量,它也不安全!您应该始终在 MYSQLI 或 PDO 中使用准备好的语句和参数化查询,而不是将变量连接到查询中。

答:

0赞 Blackegg13 9/12/2023 #1

我找到了为什么我的代码要进行双重插入。在我的php db连接中,我有这个位

if( !$conn -> query($sql) ){
    die('[ERR] ' . $conn -> error);
}

通过测试查询是否无意中工作已经插入了记录。将其从代码中删除,问题就消失了。让我意识到它不是 ajax 的是 php 中的另一个代码块,它也插入了两条记录,所以它必须只有一件事。