表单提交成功后出现Invalid Request问题:压缩图片与文本存储异常
表单上传与跳转异常问题
问题现象
- 使用compressorjs压缩图片+axios上传后,压缩图和文本能正确存入数据库,图片也保存到指定文件夹,但跳转至
direct.php时出现Invalid Request提示,触发PHP代码中$_SERVER['REQUEST_METHOD'] !== 'POST'的分支。 - 将上传按钮改为
submit后,出现双重提交异常:- 未压缩的原图被存入数据库单独一行,但未保存到图片文件夹;
- 压缩图与输入文本存入另一行,压缩图可正确保存至指定文件夹。
涉及代码
HTML代码
<body> <form action="direct.php" method="post" enctype="multipart/form-data"> <div class="mainimg"> <input type="file" id="file" accept="image/*" name="file" onchange="compressImg()"> </div> <div class="test"> <input type="text" name="test"> </div> <button type="button" onclick="uploadData()">Upload</button> </form> <script src="compressorjs-main/dist/compressor.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.6.3/axios.min.js"></script> <script> let formData; function compressImg() { const fileInput = document.getElementById('file'); const file = fileInput.files[0]; if (!file) { return; } new Compressor(file, { quality: 0.6, maxWidth: 700, maxHeight: 700, success(result) { formData = new FormData(); console.log('Original Size:', file.size); console.log('Compressed Size:', result.size); console.log("Image name after compression", result.name); // Append the compressed image formData.delete('file'); formData.append('file', result, result.name); }, error(err) { console.log(err.message); }, }); } function uploadData() { // Check if formData is defined if (formData) { // Append the test value to the formData formData.append('test', document.querySelector('[name="test"]').value); axios.post('direct.php', formData).then(() => { console.log('Upload success'); window.location.href = 'direct.php'; console.log(formData); }); } else { console.log('No data to upload'); } } </script> </body>
PHP代码
if ($_SERVER['REQUEST_METHOD'] === 'POST') { $compressedImage = $_FILES['file']; $test = $_POST['test']; echo "Original File Name: " . $compressedImage['name'] . "<br>"; echo "Original File Size: " . $compressedImage['size'] . "<br>"; $targetDir = 'accountimage/'; $targetFile = $targetDir . basename($compressedImage['name']); move_uploaded_file($compressedImage['tmp_name'], $targetFile); echo "Moved File Name: " . $compressedImage['name'] . "<br>"; echo "Moved File Size: " . filesize($targetFile) . "<br>"; $sql = "INSERT INTO gameaccount (pic, test) VALUES (?, ?)"; $stmt = $conn->prepare($sql); $stmt->bind_param("ss", $targetFile, $test); $stmt->execute(); $stmt->close(); $conn->close(); echo 'Upload good';} else {echo 'Invalid request';}
问题根源
- 跳转触发GET请求:axios完成POST上传后,执行
window.location.href = 'direct.php'会发起GET请求,而PHP代码只处理POST请求,因此返回Invalid Request。 - submit按钮触发双重提交:改为
submit按钮后,表单默认同步提交(发送未压缩原图,此时压缩后的FormData尚未生成)与axios异步提交(发送压缩图+文本)同时触发,导致数据库插入两行数据。
修复方案
方案1:调整跳转逻辑,避免GET请求触发异常
将跳转目标改为专门的成功页面,或在PHP中返回跳转指令,不在前端直接跳转direct.php:
function uploadData() { if (formData) { formData.append('test', document.querySelector('[name="test"]').value); axios.post('direct.php', formData) .then(() => { console.log('Upload success'); // 跳转到成功页面,而非处理上传的direct.php window.location.href = 'upload_success.php'; }) .catch(error => { console.error('Upload failed:', error); }); } else { console.log('No data to upload'); } }
方案2:禁用表单默认提交(保留submit按钮)
如果要使用submit按钮,需阻止表单默认提交行为,只保留axios异步提交:
- 修改HTML表单和按钮:
<form action="direct.php" method="post" enctype="multipart/form-data" onsubmit="uploadData(event)"> <!-- 其他表单元素 --> <button type="submit">Upload</button> </form>
- 修改JS函数:
function uploadData(event) { event.preventDefault(); // 阻止表单默认同步提交 if (formData) { formData.append('test', document.querySelector('[name="test"]').value); axios.post('direct.php', formData) .then(() => { console.log('Upload success'); window.location.href = 'upload_success.php'; }) .catch(err => console.error('Upload error:', err)); } else { console.log('No data to upload'); return false; } }
方案3:优化PHP逻辑兼容GET请求(不推荐)
若必须跳转到direct.php,可修改PHP代码,GET请求时显示成功信息而非Invalid Request:
if ($_SERVER['REQUEST_METHOD'] === 'POST') { $compressedImage = $_FILES['file']; $test = $_POST['test']; echo "Original File Name: " . $compressedImage['name'] . "<br>"; echo "Original File Size: " . $compressedImage['size'] . "<br>"; $targetDir = 'accountimage/'; // 确保目标目录存在,否则move_uploaded_file会失败 if (!file_exists($targetDir)) { mkdir($targetDir, 0755, true); } $targetFile = $targetDir . basename($compressedImage['name']); if (move_uploaded_file($compressedImage['tmp_name'], $targetFile)) { echo "Moved File Name: " . $compressedImage['name'] . "<br>"; echo "Moved File Size: " . filesize($targetFile) . "<br>"; $sql = "INSERT INTO gameaccount (pic, test) VALUES (?, ?)"; $stmt = $conn->prepare($sql); $stmt->bind_param("ss", $targetFile, $test); $stmt->execute(); $stmt->close(); $conn->close(); echo 'Upload good'; } else { echo 'Failed to save image'; } } else { // GET请求时显示上传完成信息 echo 'Upload completed successfully'; }
额外优化建议
- 确保
accountimage/目录存在且具备写入权限,避免move_uploaded_file失败; - 提前初始化FormData,避免未定义的情况:
let formData = new FormData(); // 提前初始化 function compressImg() { const fileInput = document.getElementById('file'); const file = fileInput.files[0]; if (!file) { return; } new Compressor(file, { quality: 0.6, maxWidth: 700, maxHeight: 700, success(result) { formData.delete('file'); // 删除旧文件,避免重复提交 formData.append('file', result, result.name); }, error(err) { console.log(err.message); }, }); }
内容的提问来源于stack exchange,提问作者Yan B
相关产品推荐
相关产品推荐

