النماذج والبيانات

الدرس 10 من 18

0% مكتمل

الفصل الثالث: تطوير الويب

النماذج والبيانات في Express

تعلم كيفية التعامل مع النماذج وإرسال البيانات من وإلى الخادم

أنواع طلبات HTTP

الطريقة الاستخدام مثال
GET جلب البيانات عرض صفحة، قائمة مستخدمين
POST إنشاء بيانات جديدة تسجيل مستخدم، إضافة منتج
PUT تحديث كامل تحديث ملف مستخدم بالكامل
PATCH تحديث جزئي تحديث اسم المستخدم فقط
DELETE حذف البيانات حذف منتج، إلغاء حساب

معالجة بيانات POST

1. إعداد Express لاستقبال البيانات:

const express = require('express'); const app = express(); // لمعالجة JSON app.use(express.json()); // لمعالجة بيانات النماذج app.use(express.urlencoded({ extended: true })); app.listen(3000, () => { console.log('Server running on port 3000'); });

2. استقبال بيانات POST:

// مثال: تسجيل مستخدم جديد app.post('/register', (req, res) => { const { username, email, password } = req.body; // التحقق من البيانات if (!username || !email || !password) { return res.status(400).json({ success: false, message: 'جميع الحقول مطلوبة' }); } // حفظ في قاعدة البيانات (مثال) console.log('مستخدم جديد:', { username, email }); res.status(201).json({ success: true, message: 'تم التسجيل بنجاح', data: { username, email } }); });

رفع الملفات

لرفع الملفات، نحتاج لمكتبة multer:

// تثبيت multer pnpm add multer // في الكود const multer = require('multer'); // إعداد التخزين const storage = multer.diskStorage({ destination: (req, file, cb) => { cb(null, 'uploads/'); }, filename: (req, file, cb) => { const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9); cb(null, file.fieldname + '-' + uniqueSuffix + path.extname(file.originalname)); } }); // تصفية الملفات (مثلاً: صور فقط) const fileFilter = (req, file, cb) => { if (file.mimetype.startsWith('image/')) { cb(null, true); } else { cb(new Error('الملف ليس صورة!'), false); } }; const upload = multer({ storage: storage, fileFilter: fileFilter, limits: { fileSize: 5 * 1024 * 1024 } // 5MB max }); // استخدام في المسار app.post('/upload', upload.single('image'), (req, res) => { if (!req.file) { return res.status(400).json({ message: 'لم يتم رفع ملف' }); } res.json({ message: 'تم رفع الملف بنجاح', filename: req.file.filename, path: req.file.path, size: req.file.size }); }); // رفع ملفات متعددة app.post('/upload-multiple', upload.array('images', 5), (req, res) => { res.json({ message: `تم رفع ${req.files.length} ملف`, files: req.files.map(f => f.filename) }); });

التحقق من البيانات (Validation)

استخدم express-validator للتحقق من البيانات:

// تثبيت pnpm add express-validator // الاستخدام const { body, validationResult } = require('express-validator'); app.post('/register', // قواعد التحقق [ body('username') .trim() .isLength({ min: 3, max: 20 }) .withMessage('اسم المستخدم يجب أن يكون بين 3-20 حرف') .isAlphanumeric() .withMessage('اسم المستخدم يجب أن يحتوي على أحرف وأرقام فقط'), body('email') .trim() .isEmail() .withMessage('البريد الإلكتروني غير صحيح') .normalizeEmail(), body('password') .isLength({ min: 8 }) .withMessage('كلمة المرور يجب أن تكون 8 أحرف على الأقل') .matches(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)/) .withMessage('كلمة المرور يجب أن تحتوي على أحرف كبيرة وصغيرة وأرقام'), body('age') .optional() .isInt({ min: 13, max: 120 }) .withMessage('العمر يجب أن يكون بين 13-120') ], // معالج المسار (req, res) => { // فحص الأخطاء const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ success: false, errors: errors.array() }); } // البيانات صحيحة، تابع المعالجة const { username, email, password, age } = req.body; res.json({ success: true, message: 'البيانات صحيحة', data: { username, email, age } }); } );

أمان النماذج

نصائح أمنية مهمة

  • لا تثق أبداً ببيانات المستخدم: تحقق دائماً من البيانات الواردة
  • استخدم HTTPS: لتشفير البيانات أثناء الإرسال
  • حماية من CSRF: استخدم tokens لحماية من Cross-Site Request Forgery
  • تنظيف البيانات: أزل أي أكواد خبيثة (XSS)
  • Rate Limiting: حدد عدد الطلبات لمنع الهجمات

مثال: حماية من CSRF

// تثبيت csurf pnpm add csurf const csrf = require('csurf'); const csrfProtection = csrf({ cookie: true }); app.use(require('cookie-parser')()); // عرض نموذج مع CSRF token app.get('/form', csrfProtection, (req, res) => { res.render('form', { csrfToken: req.csrfToken() }); }); // معالجة النموذج مع التحقق من CSRF app.post('/process', csrfProtection, (req, res) => { res.send('البيانات آمنة!'); });

مثال: Rate Limiting

// تثبيت pnpm add express-rate-limit const rateLimit = require('express-rate-limit'); // حد 100 طلب كل 15 دقيقة const limiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 100, message: 'تجاوزت الحد المسموح من الطلبات، حاول لاحقاً' }); // تطبيق على جميع المسارات app.use(limiter); // أو على مسار محدد app.post('/login', limiter, (req, res) => { // ... });

مثال شامل: نظام تسجيل

const express = require('express'); const { body, validationResult } = require('express-validator'); const bcrypt = require('bcrypt'); const app = express(); app.use(express.json()); app.use(express.urlencoded({ extended: true })); // قاعدة بيانات وهمية const users = []; // صفحة التسجيل (HTML) app.get('/register', (req, res) => { res.send(` التسجيل

التسجيل

`); }); // معالجة التسجيل app.post('/register', [ body('username').trim().isLength({ min: 3 }).isAlphanumeric(), body('email').trim().isEmail().normalizeEmail(), body('password').isLength({ min: 8 }), body('age').optional().isInt({ min: 13 }) ], async (req, res) => { // فحص الأخطاء const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ errors: errors.array() }); } const { username, email, password, age } = req.body; // التحقق من عدم وجود المستخدم const exists = users.find(u => u.email === email); if (exists) { return res.status(400).json({ message: 'البريد الإلكتروني مستخدم بالفعل' }); } // تشفير كلمة المرور const hashedPassword = await bcrypt.hash(password, 10); // حفظ المستخدم users.push({ id: users.length + 1, username, email, password: hashedPassword, age: age || null, createdAt: new Date() }); res.status(201).json({ success: true, message: 'تم التسجيل بنجاح', user: { username, email } }); } ); // عرض المستخدمين app.get('/users', (req, res) => { res.json({ count: users.length, users: users.map(u => ({ id: u.id, username: u.username, email: u.email, age: u.age })) }); }); app.listen(3000, () => { console.log('Server: http://localhost:3000'); });

الخلاصة

  • استخدم express.json() و express.urlencoded() لمعالجة البيانات
  • multer لرفع الملفات
  • express-validator للتحقق من البيانات
  • لا تثق أبداً ببيانات المستخدم
  • استخدم CSRF protection و Rate Limiting للأمان
  • شفر كلمات المرور دائماً (bcrypt)