原生html+js+css+php多图上传带预览可增删,前后端判断图片大小和后缀
html
源码来自AI,有改动,整合亲测可用
html
<?php
// 设置允许的最大文件大小为 2MB
$maxFileSize = 2 * 1024 * 1024;
$allowedExtensions = ['jpg', 'jpeg', 'png', 'gif'];
// 上传目录(请确保目录存在并具备写入权限)
$uploadDir = __DIR__ . '/uploads/';
$response = [
'success' => false,
'url' => '',
'error' => ''
];
if (isset($_GET['act']) && $_GET['act'] === 'up') {
if (isset($_FILES['file']) && $_FILES['file']['error'] === UPLOAD_ERR_OK) {
if (!is_dir($uploadDir)) { @mkdir($uploadDir, 0755, true); }
$file = $_FILES['file'];
// 检查文件大小
if ($file['size'] > $maxFileSize) {
$response['error'] = '文件大小不能超过 2MB';
echo json_encode($response);
exit;
}
// 检查文件扩展名
$fileExtension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
if (!in_array($fileExtension, $allowedExtensions)) {
$response['error'] = '仅支持 jpg, jpeg, png, gif 格式';
echo json_encode($response);
exit;
}
// 为文件生成唯一名称
$newFileName = uniqid('img_', true) . '.' . $fileExtension;
$targetFilePath = $uploadDir . $newFileName;
// 移动上传文件到目标目录
if (move_uploaded_file($file['tmp_name'], $targetFilePath)) {
$response['success'] = true;
$response['url'] = '/uploads/' . $newFileName; // 根据实际路径配置返回 URL
} else {
$response['error'] = '文件上传失败,请重试';
}
} else {
$response['error'] = '上传文件不存在或上传出错';
}
header('Content-Type: application/json');
echo json_encode($response);
exit();
}
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>多图片上传带进度条</title>
<style>
* {
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
padding: 20px;
}
.form-container {
max-width: 600px;
margin: auto;
background-color: #fff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
font-weight: bold;
margin-bottom: 5px;
}
.form-group input[type="text"] {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
}
.upload-container {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-top: 10px;
}
.image-preview {
position: relative;
width: 120px;
height: 120px;
border: 2px solid #ddd;
border-radius: 4px;
overflow: hidden;
background-color: #f5f5f5;
display: flex;
align-items: center;
justify-content: center;
}
.image-preview img {
width: 100%;
height: 100%;
object-fit: cover;
}
.delete-btn {
position: absolute;
top: 5px;
right: 5px;
background-color: rgba(255, 0, 0, 0.7);
color: #fff;
border: none;
border-radius: 50%;
cursor: pointer;
width: 20px;
height: 20px;
display: flex;
align-items: center;
justify-content: center;
}
.progress-bar {
width: 100%;
background-color: #f3f3f3;
height: 10px;
border-radius: 5px;
overflow: hidden;
margin-top: 5px;
display: none;
}
.progress-fill {
height: 100%;
background-color: #0073e6;
width: 0;
transition: width 0.2s;
}
.hidden-textarea {
width: 100%;
height: 80px;
margin-top: 10px;
display: none;
}
.upload-btn {
display: flex;
align-items: center;
justify-content: center;
width: 120px;
height: 120px;
border: 2px dashed #0073e6;
border-radius: 4px;
cursor: pointer;
color: #0073e6;
font-size: 1em;
background-color: #f9f9f9;
}
.upload-btn input {
display: none;
}
.btn-submit {
width: 100%;
padding: 10px;
font-size: 1.1em;
background-color: #0073e6;
color: #fff;
border: none;
border-radius: 4px;
cursor: pointer;
margin-top: 20px;
}
</style>
</head>
<body>
<div class="form-container">
<h2>招聘信息图片上传</h2>
<!-- 标题输入框 -->
<div class="form-group">
<label for="title">标题</label>
<input type="text" id="title" placeholder="请输入图片标题">
</div>
<!-- 图片上传容器 -->
<div class="upload-container" id="upload-container">
<div class="upload-btn" onclick="document.getElementById('image-upload-input').click();">
+ 上传图片
<input type="file" id="image-upload-input" accept="image/*" onchange="prepareImageForUpload(event)">
</div>
</div>
<!-- 已上传图片路径和显示上传图片的URL -->
<textarea id="uploaded-images-path" class="hidden-textarea" readonly></textarea>
<textarea id="uploaded-images-url" class="hidden-textarea" placeholder="已传图" readonly></textarea>
<!-- 提交按钮 -->
<button class="btn-submit" onclick="uploadAllImages()">提交上传</button>
</div>
<script>
const MAX_IMAGES = 5; // 最大上传图片数量
const MAX_FILE_SIZE = 2 * 1024 * 1024; // 文件大小限制为2MB
const allowedExtensions = ['jpg', 'jpeg', 'png', 'gif']; // 允许的文件格式
const imagesToUpload = []; // 存储图片文件对象
// 选择图片准备上传
function prepareImageForUpload(event) {
const file = event.target.files[0];
if (!file) return;
// 检查文件大小
if (file.size > MAX_FILE_SIZE) {
alert("文件大小不能超过2MB");
return;
}
// 检查文件格式
const fileExtension = file.name.split('.').pop().toLowerCase();
if (!allowedExtensions.includes(fileExtension)) {
alert("仅支持jpg, jpeg, png, gif格式");
return;
}
imagesToUpload.push(file);
displayImagePreview(file);
// 更新上传按钮显示
if (imagesToUpload.length >= MAX_IMAGES) {
document.querySelector('.upload-btn').style.display = 'none';
}
}
// 显示图片预览
function displayImagePreview(file) {
const reader = new FileReader();
reader.onload = function(e) {
const uploadContainer = document.getElementById('upload-container');
const imagePreview = document.createElement('div');
imagePreview.className = 'image-preview';
const img = document.createElement('img');
img.src = e.target.result;
imagePreview.appendChild(img);
const deleteBtn = document.createElement('button');
deleteBtn.className = 'delete-btn';
deleteBtn.innerText = '×';
deleteBtn.onclick = () => removeImage(imagePreview, file);
imagePreview.appendChild(deleteBtn);
const progressBar = document.createElement('div');
progressBar.className = 'progress-bar';
const progressFill = document.createElement('div');
progressFill.className = 'progress-fill';
progressBar.appendChild(progressFill);
imagePreview.appendChild(progressBar);
uploadContainer.insertBefore(imagePreview, uploadContainer.lastElementChild);
};
reader.readAsDataURL(file);
}
// 删除图片
function removeImage(imageElement, file) {
imageElement.remove();
const index = imagesToUpload.indexOf(file);
if (index > -1) imagesToUpload.splice(index, 1);
// 显示上传按钮
if (imagesToUpload.length < MAX_IMAGES) {
document.querySelector('.upload-btn').style.display = 'flex';
}
}
// 提交上传所有图片
function uploadAllImages() {
if (!imagesToUpload.length) {
alert("请上传至少一张图片");
return;
}
const uploadedUrls = []; // 用于存储成功上传的图片 URL
const uploadedImagesPath = document.getElementById('uploaded-images-url');
uploadedImagesPath.style.display = 'block';
imagesToUpload.forEach((file, index) => {
// 模拟上传过程
const progressFill = document.querySelectorAll('.progress-fill')[index];
progressFill.style.width = '0%';
const formData = new FormData();
formData.append("file", file);
const xhr = new XMLHttpRequest();
xhr.open("POST", "?act=up&t=", true);
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
const percentComplete = (e.loaded / e.total) * 100;
progressFill.style.width = percentComplete + '%';
}
};
xhr.onload = function() {
if (xhr.status === 200) {
const response = JSON.parse(xhr.responseText);
if (response.success) {
uploadedUrls.push(response.url);
uploadedImagesPath.value = uploadedUrls.join('\n');
} else {
alert("上传失败:" + response.error);
}
}
};
xhr.send(formData);
});
}
</script>
</body>
</html>