Aplikasi upload file sederhana berbasis Node.js + Express. File disimpan langsung ke database MySQL sebagai binary (BLOB), dilindungi oleh Cloudflare Turnstile untuk mencegah spam upload.
- Upload file hingga 10 MB via drag & drop atau file picker
- File disimpan di MySQL sebagai BLOB (tidak butuh storage eksternal)
- Proteksi Cloudflare Turnstile di endpoint upload
- Nama file di-randomize saat disimpan
- Security headers di setiap response JSON (
X-Frame-Options,CSP,X-Content-Type-Options) - Halaman 404 custom
- Runtime: Node.js
- Framework: Express 5
- Database: MySQL (via
mysql2) - Upload: Multer (memory storage)
- Captcha: Cloudflare Turnstile
- HTTP Client: Axios
.
├── app.js # Entry point, route definitions
├── db.js # MySQL connection pool
├── public/
│ ├── index.html # Halaman upload
│ └── 404.html # Halaman 404
├── .env # Konfigurasi environment (tidak di-commit)
├── package.json
└── README.md
git clone https://github.com/username/filevault.git
cd filevault
npm installCREATE DATABASE my_database;
USE my_database;
CREATE TABLE files (
id INT AUTO_INCREMENT PRIMARY KEY,
filename VARCHAR(255) NOT NULL,
mimetype VARCHAR(100) NOT NULL,
data LONGBLOB NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);Buat file .env di root proyek:
DB_HOST=localhost
DB_USER=root
DB_PASS=password_kamu
DB_NAME=my_database
CLOUDFLARE_TURNSTILE_SECRET_KEY=secret_key_kamuUntuk mendapatkan Turnstile key, daftarkan domain di Cloudflare Turnstile Dashboard.
# Production
npm start
# Development (auto-reload)
npm run devServer berjalan di http://localhost:2004
Upload file. Request harus berupa multipart/form-data.
| Field | Type | Keterangan |
|---|---|---|
file |
File | File yang diupload, maks. 10 MB |
cf-turnstile-response |
String | Token Turnstile dari widget |
Response sukses:
{
"success": true,
"filename": "1718000000000-123456.png",
"path": "/files/1718000000000-123456.png"
}Response error:
{
"error": "Captcha token is missing"
}Mengambil file berdasarkan nama. Response langsung berupa binary file dengan Content-Type sesuai mimetype aslinya.
GET /files/1718000000000-123456.png
- File disimpan sebagai BLOB di MySQL. Untuk skala besar, pertimbangkan pindah ke object storage (S3, R2, dll).
- Pastikan
.envmasuk ke.gitignoreagar credential tidak ter-commit.
node_modules/
.env