向ChatGPT学习(二)

247 阅读2分钟

以下代码未验证

问:实现一个文件上传页面,规定上传文件大小不能大于20M。前端使用fetch,后端使用PHP,实现文件切片上传,上传后合并切片,将合并后的完整文件保存到服务器/var/www/upload目录下。

答:以下是一个简单的文件上传页面示例,规定上传文件大小不超过 20MB,前端使用 Fetch API 进行文件切片上传,后端使用 PHP 处理文件切片上传和合并,并将合并后的文件保存到服务器指定目录。

前端 HTML 页面代码:

<!DOCTYPE html>
<html>
<head>
    <title>文件上传</title>
</head>
<body>
    <h1>文件上传</h1>
    <input type="file" id="fileInput">
    <button onclick="uploadFile()">上传</button>
    <script>
        function uploadFile() {
            const fileInput = document.getElementById('fileInput');
            const file = fileInput.files[0];
            
            if (!file) {
                alert('请选择文件');
                return;
            }
            
            if (file.size > 20 * 1024 * 1024) {
                alert('文件大小不能超过20M');
                return;
            }
            
            // 分片上传
            const chunkSize = 2 * 1024 * 1024; // 每个分片的大小(2M)
            let start = 0;
            let end = Math.min(chunkSize, file.size);
            let index = 0;
            
            const uploadChunk = () => {
                const chunk = file.slice(start, end);
                const formData = new FormData();
                formData.append('chunk', chunk);
                formData.append('index', index);
                formData.append('fileName', file.name);
                
                fetch('/upload.php', {
                    method: 'POST',
                    body: formData
                })
                .then(response => response.json())
                .then(data => {
                    console.log(data);
                    if (end < file.size) {
                        start = end;
                        end = Math.min(start + chunkSize, file.size);
                        index++;
                        uploadChunk();
                    } else {
                        // 文件上传完成
                        console.log('文件上传完成');
                        
                        // 请求合并文件
                        fetch('/merge.php', {
                            method: 'POST',
                            body: JSON.stringify({fileName: file.name})
                        })
                        .then(response => response.json())
                        .then(data => {
                            console.log(data);
                        })
                        .catch(error => {
                            console.error(error);
                        });
                    }
                })
                .catch(error => {
                    console.error(error);
                });
            };
            
            uploadChunk();
        }
    </script>
</body>
</html>

后端代码(PHP):

upload.php:

<?php
$targetDirectory = '/var/www/upload/';
$fileName = $_POST['fileName'];
$index = $_POST['index'];
$chunk = $_FILES['chunk'];

$targetPath = $targetDirectory . $fileName . '.' . $index;
move_uploaded_file($chunk['tmp_name'], $targetPath);

$response = [
    'status' => 'success',
    'message' => '分片上传成功',
    'data' => [
        'index' => $index
    ]
];
header('Content-Type: application/json');
echo json_encode($response);

merge.php:

<?php
$targetDirectory = '/var/www/upload/';
$fileName = $_POST['fileName'];
$targetPath = $targetDirectory . $fileName;

$index = 0;
$chunkPath = $targetDirectory . $fileName . '.' . $index;
$handle = fopen($targetPath, 'wb');

while (file_exists($chunkPath)) {
    $chunkData = file_get_contents($chunkPath);
    fwrite($handle, $chunkData);
    unlink($chunkPath);
    $index++;
    $chunkPath = $targetDirectory . $fileName . '.' . $index; 
}
    
fclose($handle);

$response = [ 
  'status' => 'success', 
  'message' => '文件合并成功', 
  'data' => [ 
    'fileName' => $fileName, 
    'filePath' => $targetPath 
  ] 
]; 

header('Content-Type: application/json'); 
echo json_encode($response);

上面的代码演示了一个简单的文件切片上传和合并的示例,其中前端使用了Fetch API来进行文件上传,后端使用了PHP来处理上传的文件切片和合并文件。在前端,我们使用了slice()方法来将文件切片,并通过FormData将切片和其他参数一同发送到后端。后端接收到切片后,将其保存到指定目录,并在所有切片上传完成后进行文件合并操作。

请注意,这只是一个简单的示例,实际应用中还需要考虑文件上传的安全性、错误处理、并发上传的处理等。此外,服务器上的文件目录和权限设置也需要根据实际情况进行配置和保护。在实际生产环境中,建议使用现有的文件上传库或框架,它们通常会提供更全面和安全的文件上传解决方案。