تقنية

كيفية إنشاء نموذج HTML لتحميل الملفات إلى Google Cloud Storage


دعنا نكتب تطبيق ويب بسيط يسمح للمستخدمين بتحميل الملفات إلى Google Cloud Storage دون مصادقة. سيكون لموقع العميل للتطبيق نموذج HTML مع حقول إدخال واحدة أو أكثر. جانب الخادم هو تطبيق Node.js الذي سيتعامل مع تحميل الملف. قد يتم نشر التطبيق في Google Cloud Run أو Firebase Function أو كدالة Google Cloud.

شكل HTML

يتضمن نموذج HTML لدينا حقل اسم وحقل إدخال ملف يقبل ملفات الصور فقط. كلا الحقول مطلوبة.

عندما يقوم المستخدم بتقديم النموذج ، يتم إرسال بيانات النموذج إلى الخادم ، المشفر على أنها multipart/form-data ، باستخدام واجهة برمجة تطبيقات Fetch. سيقوم الخادم بالتحقق من صحة بيانات النموذج وإذا كان النموذج صالحًا ، فسيتم تحميل الملف إلى Google Cloud Storage.

<form method="post" enctype="multipart/form-data">
  <input type="text" name="name" id="name" placeholder="Your name" required />
  <input type="file" name="image" accept="image/*" required />
  <input type="submit" value="Submit Form" />
</form>

<script>
  const formElem = document.querySelector('form');
  formElem.addEventListener('submit', async (e) => {
    e.preventDefault();
    const formData = new FormData();
    formData.append('name', e.target[0].value);
    formData.append('file', e.target[1].files[0]);
    const response = await fetch('/submitform', {
      method: 'POST',
      body: formData,
    });
    const data = await response.text();
    return data;
  });
</script>

تطبيق node.js

سيكون لتطبيقنا طريقين:

  1. مسار المنزل (/) الذي سيعرض النموذج.
  2. مسار النموذج الإرسال الذي سيتعامل مع تحميل الملف.
// index.js
const express = require('express');
const router = require('./router');

const app = express();

app.get("https://www.labnol.org/", (_, res) => {
  res.sendFile(`${__dirname}/index.html`);
});

app.use(express.json({ limit: '50mb' }));
app.use(express.urlencoded({ extended: true, limit: '50mb' }));
app.use(router);

app.listen(process.env.PORT || 8080, async () => {
  console.log('listening on port 8080');
});

نظرًا لأن خادم Express لا يمكنه التعامل مع بيانات النماذج متعددة الأجزاء ، فإننا نستخدم Multer Middleware لتحليل بيانات النموذج التي تتضمن كل من محتوى النص والبيانات الثنائية. أيضًا ، نحن نتجاهل اسم الملف الأصلي للملف الذي تم تحميله وتعيين اسم الملف الفريد الذي تم إنشاؤه من uuid مكتبة.

// router.js
const express = require('express');
const { Storage } = require('@google-cloud/storage');
const { v4: uuidv4 } = require('uuid');
const multer = require('multer');

const storage = new Storage();
const router = express.Router();
const upload = multer();

router.post('/submit', upload.single('file'), async (req, res) => {
  const { name } = req.body;
  const { mimetype, originalname, size } = req.file;
  if (!mimetype || mimetype.split("https://www.labnol.org/")[0] !== 'image') {
    return res.status(400).send('Only images are allowed');
  }
  if (size > 10485760) {
    return res.status(400).send('Image must be less than 10MB');
  }
  const bucketName = '<<GOOGLE_CLOUD_STORAGE_BUCKET_NAME>>';
  const fileExtension = originalname.split('.').pop();
  const fileName = `${uuidv4()}.${fileExtension}`;
  const file = storage.bucket(bucketName).file(fileName);
  await file.save(req.file.buffer, {
    contentType: mimetype,
    resumable: false,
    public: true,
  });
  const url = `https://storage.googleapis.com/${bucketName}/${fileName}`;
  console.log(`File uploaded by ${name}`, url);
  return res.status(200).send(url);
});

module.exports = router;

باستخدام وظائف Firebase

إذا كنت تخطط لنشر تطبيق تحميل الملفات على وظائف Firebase ، فسيكون هناك حاجة إلى بعض التغييرات لأن البرامج الوسيطة Multer لدينا غير متوافقة مع وظائف Firebase.

كحل بديل ، يمكننا تحويل الصورة إلى BASE64 على جانب العميل ثم تحميل الصورة إلى Google Cloud Storage. بدلاً من ذلك ، يمكنك استخدام Busboy الوسيطة لتحليل بيانات النموذج.

const convertBase64 = (file) => {
  return new Promise((resolve, reject) => {
    const fileReader = new FileReader();
    fileReader.readAsDataURL(file);
    fileReader.onload = () => {
      const base64String = fileReader.result;
      const base64Image = base64String.split(';base64,').pop();
      resolve(base64Image);
    };
    fileReader.onerror = (error) => {
      reject(error);
    };
  });
};

const handleUpload = async (file) => {
  const base64 = await convertBase64(file);
  const { type, size, name } = file;

  const response = await fetch('/submitform', {
    headers: { 'Content-Type': 'application/json' },
    method: 'POST',
    body: JSON.stringify({ type, size, name, base64 }),
  });

  const url = await response.text();
  console.log(`File uploaded by ${name}`, url);
};

سيتعين تعديل معالج النموذج الإرسال لتحويل صورة BASE64 إلى مخزن مؤقت ثم تحميل الصورة إلى Google Cloud Storage.

router.post('/upload', async (req, res) => {
  const { name, type, size, base64 } = req.body;
  const buffer = Buffer.from(base64, 'base64');
  await file.save(buffer, {
    contentType: type,
    resumable: false,
    public: true,
  });
  return res.send(`File uploaded`);
});

كورز لطلبات الأصل

إذا كنت تخدم النموذج في مجال مختلف عن معالج النموذج ، فستحتاج إلى إضافة ملف cors الوسيطة لتطبيقك.

const cors = require('cors')({ origin: true });
app.use(cors);

يجب عليك تعيين سياسة التحكم في الوصول الخاصة بجرافة تخزين السحابة الخاصة بك إلى “الحبيبات الدقيقة” وليس “موحدة”. عندما يتم تحميل الملفات الفردية على التخزين السحابي ، فهي عامة ولكن مجلد الحاوية لا يزال خاصًا.



Source link


اكتشاف المزيد من مرابع التكنولوجيا

اشترك للحصول على أحدث التدوينات المرسلة إلى بريدك الإلكتروني.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *

زر الذهاب إلى الأعلى

اكتشاف المزيد من مرابع التكنولوجيا

اشترك الآن للاستمرار في القراءة والحصول على حق الوصول إلى الأرشيف الكامل.

Continue reading