Hướng dẫn html upload file to google drive - html tải tệp lên google drive

Hướng dẫn này giải thích cách bạn có thể xây dựng biểu mẫu tải lên tệp để tải tệp lên Google Cloud Storage. Các tập tin được tải lên có thể được thực hiện công khai hoặc riêng tư.

Hãy để viết một ứng dụng web đơn giản cho phép người dùng tải lên các tệp lên Google Cloud Storage mà không cần xác thực. Trang web máy khách của ứng dụng sẽ có biểu mẫu HTML với một hoặc nhiều trường đầu vào. Phía máy chủ là ứng dụng Node.js sẽ xử lý tải lên tệp. Ứng dụng có thể được triển khai cho Google Cloud Run, chức năng Firebase hoặc là chức năng Google Cloud.

Hình thức HTML

Biểu mẫu HTML của chúng tôi bao gồm trường tên và trường đầu vào tệp chỉ chấp nhận các tệp hình ảnh. Cả hai trường được yêu cầu.

Khi người dùng gửi biểu mẫu, dữ liệu biểu mẫu được gửi đến máy chủ, được mã hóa dưới dạng nhiều dữ liệu/biểu mẫu, sử dụng API tìm nạp. Máy chủ sẽ xác thực dữ liệu biểu mẫu và nếu biểu mẫu hợp lệ, nó sẽ tải tệp lên 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>

Ứng dụng Node.js

Ứng dụng của chúng tôi sẽ có hai tuyến đường:

  1. Tuyến đường () sẽ hiển thị biểu mẫu.
  2. Tuyến biểu mẫu gửi sẽ xử lý tải lên tệp.

// index.js
const express = require('express');
const router = require('./router');

const app = express();

app.get('/', (_, 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');
});

Vì máy chủ Express không thể xử lý dữ liệu biểu mẫu nhiều phần, chúng tôi đang sử dụng phần mềm trung gian Multer để phân tích dữ liệu biểu mẫu bao gồm cả nội dung văn bản và dữ liệu nhị phân. Ngoài ra, chúng tôi đang loại bỏ tên tệp gốc của tệp được tải lên và được gán tên tệp duy nhất của chúng tôi được tạo từ thư viện 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('/')[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 = '<>';
  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;

Sử dụng các chức năng Firebase

Nếu bạn đang có kế hoạch triển khai ứng dụng tải lên tệp của mình lên các chức năng Firebase, một số thay đổi được yêu cầu vì phần mềm trung gian Multer của chúng tôi không tương thích với các chức năng Firebase.

Là một cách giải quyết, chúng ta có thể chuyển đổi hình ảnh thành Base64 ở phía máy khách và sau đó tải hình ảnh lên Google Cloud Storage. Ngoài ra, bạn có thể sử dụng phần mềm trung gian Busboy để phân tích dữ liệu biểu mẫu.

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);
};

Trình xử lý biểu mẫu gửi sẽ phải được điều chỉnh để chuyển đổi hình ảnh Base64 thành bộ đệm và sau đó tải hình ảnh lên 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 cho các yêu cầu có nguồn gốc chéo

Nếu bạn đang phục vụ biểu mẫu trên một miền khác với trình xử lý biểu mẫu, bạn sẽ cần thêm phần mềm trung gian cors vào ứng dụng của mình.

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

Bạn nên đặt chính sách kiểm soát truy cập của nhóm lưu trữ đám mây Google của mình thành các loại hạt mịn và không phải là đồng phục. Khi các tệp riêng lẻ được tải lên lưu trữ đám mây, chúng là công khai nhưng thư mục container vẫn còn riêng tư.