File size: 4,600 Bytes
ea617ca
c711964
 
2c5d2c8
6d2b69a
ea617ca
 
c711964
 
 
ea617ca
c711964
 
ea617ca
14517da
 
 
 
 
 
 
 
 
 
 
f07887f
14517da
 
 
 
 
 
1b9102d
 
 
 
 
 
 
 
 
 
 
 
 
 
0d9c490
 
 
 
 
 
 
 
1b9102d
 
 
6df2a5e
1b9102d
 
 
 
 
14517da
 
 
 
 
 
c711964
ea617ca
c711964
 
 
 
f07887f
c711964
 
 
 
 
 
 
2c5d2c8
 
 
 
 
 
 
 
 
c711964
9491d75
6df2a5e
 
d728393
 
 
f07887f
2c5d2c8
 
d728393
2c5d2c8
840dc0d
6d2b69a
 
840dc0d
 
c711964
 
0d9c490
 
f07887f
b30e091
c711964
ea617ca
c711964
 
ea617ca
 
 
56bfde3
ea617ca
c711964
2c5d2c8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
const express = require('express');
const multer = require('multer');
const JSZip = require('jszip');
const { createCanvas } = require('canvas');
const crypto = require('crypto');
const app = express();

// 设置 multer 用于处理文件上传
const storage = multer.memoryStorage();
const upload = multer({ storage: storage });

app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// 新增 GET / 路由来提供前端页面
app.get('/', (req, res) => {
  res.send(`
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>File Upload</title>
    </head>
    <body>
        <h1>Pic Zip a File</h1>
        <form id="uploadForm" action="/upload" method="post" enctype="multipart/form-data">
            <input type="file" id="fileInput" name="file" required>
            <button type="submit">Upload</button>
        </form>
        <script>
            document.getElementById('uploadForm').addEventListener('submit', async (event) => {
                event.preventDefault();
                const formData = new FormData(event.target);
                const response = await fetch(event.target.action, {
                    method: 'POST',
                    body: formData
                });
                if (response.ok) {
                    response.blob().then(blob => {
                        const url = window.URL.createObjectURL(blob);
                        const a = document.createElement('a');
                        a.style.display = 'none';
                        a.href = url;
                        // 从Content-Disposition头中提取文件名
                        const contentDisposition = response.headers.get('Content-Disposition');
                        const match = contentDisposition.match(/filename="?([^;\"]+)"?/);
                        if (match) {
                            const fileName = decodeURIComponent(match[1]);
                            console.log(fileName);
                            a.download = fileName;
                        } else {
                            console.error('Filename not found');
                        }
                        document.body.appendChild(a);
                        a.click();
                        window.URL.revokeObjectURL(url);
                       // alert('File downloaded successfully!');
                    });
                } else {
                    alert('Failed to upload file.');
                }
            });
        </script>
    </body>
    </html>
  `);
});

app.post('/upload', upload.single('file'), async (req, res) => {
  try {
    const file = req.file;
    const fileName = file.originalname;
    const fileType = file.mimetype;
    const fileBuffer = file.buffer;
    const hostname = req.hostname;

    // 压缩文件成 zip 格式
    const zip = new JSZip();
    zip.file(fileName, fileBuffer);
    const zipBuffer = await zip.generateAsync({ type: 'nodebuffer' });

    // 创建包含文件信息的表格图片
    const width = 400;
    const height = 300;
    const canvas = createCanvas(width, height);
    const ctx = canvas.getContext('2d');
    ctx.fillStyle = '#FFFFFF';
    ctx.fillRect(0, 0, width, height);
    ctx.fillStyle = '#000000';
    ctx.font = '20px WenQuanYi Zen Hei';

    const text = `
File  Name: ${fileName}
File   Type: ${fileType}
File   Size: ${fileBuffer.length} bytes
Created At: ${new Date().toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })}
Created By: ${hostname}
`;

    ctx.fillText(text.trim(), 10, 100);
    const rawImageData = canvas.toBuffer('image/jpeg', { quality: 0.75 });

    const finalBuffer = Buffer.concat([rawImageData, zipBuffer]);
    const outputFileName = encodeURIComponent(fileName.replace(/\.[^/.]+$/, "") + '-pic.zip.jpg');

    // 生成随机的哈希值作为文件名
    //const hash = crypto.randomBytes(16).toString('hex');
    //const outputFileName = encodeURIComponent(hash + '-pic.zip.jpg');

    res.setHeader('Content-Type', 'image/jpeg');
    // 使用 filename 参数来设置文件名
    res.setHeader('Content-Disposition', `attachment; filename="${outputFileName}"`);
   // console.log(`Content-Disposition header is set to: ${res.getHeader('Content-Disposition')}`);

    res.send(finalBuffer);
  } catch (error) {
    console.error(error);
    res.status(500).send('An error occurred');
  }
});

const PORT = process.env.PORT || 7860;
app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});