PHP接口在Chromium系浏览器中查询重复执行的问题排查与修复
Chromium浏览器中PHP脚本重复执行INSERT的修复方案
先从前端Angular代码入手(问题大概率出在这)
既然Postman和Firefox/Mullvad里请求都正常,说明后端逻辑本身没问题,问题基本出在Angular的请求触发逻辑上:
- 检查请求是否被多次订阅/调用:看看你的组件代码里,是不是对同一个请求执行了多次
subscribe(),或者在多个地方(比如ngOnInit和模板点击事件)都调用了提交请求的方法。举个常见错误例子:// 错误写法:两次调用并订阅同一个请求 this.traitementService.addTraitement(formData).subscribe(); // 不小心又写了一次 this.traitementService.addTraitement(formData).subscribe(); - 检查表单提交事件:如果是通过表单触发的请求,别同时给按钮加
(click)事件和表单加(ngSubmit)事件——这会导致点击按钮时触发两次提交。 - 排查HTTP拦截器:如果项目里用了HTTP拦截器,检查拦截器代码是不是无意中重复调用了
next.handle(request),导致请求被发送两次。
后端PHP做防御性修复(避免重复数据)
就算前端问题解决,后端也得做幂等处理,防止意外的重复请求搞乱数据:
- 用事务包裹批量操作:把两个INSERT放到同一个事务里,确保要么都成功,要么都回滚,避免只插入了其中一张表的重复数据:
public function addTraitement($id,$nom,$date,$nomprenom,$Nom_Medecin,$Prenom_Medecin) { $result; $con=connect(); if($con!=null) { try { $con->begin_transaction(); // 开启事务 $con->query("INSERT INTO `traitement`( `id_Patient`, `Nom_Traitement`, `Date_de_Debut`) values('" . $id . "','" . $nom . "',STR_TO_DATE('" . $date . "', '%d/%m/%Y'));"); $con->query("insert into `historique`(`Nom_Patient`, `Nom_Medecin`, `Prenom_Medecin`, `Action`) values('" . $nomprenom . "','" . $Nom_Medecin . "','" . $Prenom_Medecin . "','Ajouter Traitement')"); $con->commit(); // 提交事务 $result = array("result" => "Success"); echo json_encode($result); } catch (Exception $e) { $con->rollback(); // 出错回滚 $result = array("result" => "Failure"); echo json_encode($result); } } else{ $result = array("result" => "Failure"); echo json_encode($result); } return -1; } - 加数据库唯一约束:根据业务逻辑,给
traitement表加组合唯一索引(比如id_Patient+Nom_Traitement+Date_de_Debut),这样重复插入会直接触发数据库报错,不会产生重复数据。 - 修复SQL注入漏洞:你当前的代码直接把参数拼进SQL里,风险极高,改成参数化查询不仅安全,还能避免参数格式问题导致的意外:
public function addTraitement($id,$nom,$date,$nomprenom,$Nom_Medecin,$Prenom_Medecin) { $result; $con=connect(); if($con!=null) { try { $con->begin_transaction(); // 处理traitement表插入 $stmt = $con->prepare("INSERT INTO `traitement`(`id_Patient`, `Nom_Traitement`, `Date_de_Debut`) VALUES (?, ?, STR_TO_DATE(?, '%d/%m/%Y'))"); $stmt->bind_param("sss", $id, $nom, $date); $stmt->execute(); $stmt->close(); // 处理historique表插入 $stmt = $con->prepare("INSERT INTO `historique`(`Nom_Patient`, `Nom_Medecin`, `Prenom_Medecin`, `Action`) VALUES (?, ?, ?, 'Ajouter Traitement')"); $stmt->bind_param("sss", $nomprenom, $Nom_Medecin, $Prenom_Medecin); $stmt->execute(); $stmt->close(); $con->commit(); $result = array("result" => "Success"); echo json_encode($result); } catch (Exception $e) { $con->rollback(); $result = array("result" => "Failure"); echo json_encode($result); } } else{ $result = array("result" => "Failure"); echo json_encode($result); } return -1; }
最后检查Chromium浏览器本身
- 禁用所有扩展:有些广告拦截、代理类扩展可能会修改或重复发送请求,先禁用所有扩展再测试。
- 查看网络请求详情:按F12打开开发者工具,切换到Network标签,看看是不是真的发送了两次请求,从Initiator列能看到请求的发起来源,方便定位问题。
内容的提问来源于stack exchange,提问作者Abdellatif ENNajy
相关产品推荐
相关产品推荐

