Tệp đơn, nhiều tệp, kéo và dán, mọi thứ bạn cần biết
Hình ảnh của tác giảTải lên tệp là một chức năng phổ biến cho một dự án web. Tôi tin rằng tất cả mọi người đã gặp phải các yêu cầu liên quan ít nhiều trong quá trình phát triển.
Trong bài viết này, tôi đã tóm tắt một số kịch bản và giải pháp, hy vọng sẽ giúp bạn nắm bắt triệt để các câu hỏi liên quan đến tải lên tệp.
Mục tiêu của chúng tôi
Đầu tiên, hãy để Lừa làm rõ các chức năng cụ thể của việc tải lên tệp.
Theo mục tiêu tải lên, có 3 nhiệm vụ loại:
- Tải lên một tệp duy nhất
- Tải lên nhiều tệp cùng một lúc
- Tải lên toàn bộ thư mục
Theo các hành động của người dùng, có:
- Chọn một tệp tải lên
- Kéo tệp vào hộp sau đó tải lên
- Tải lên từ clipboard
Từ góc độ hiệu suất, chúng ta có thể cần:
- Tải lên sau khi nén một tệp
- Chia một tệp lớn thành các khối sau đó tải lên
Và ngoài ra, đôi khi chúng tôi không được tải lên các tệp trong trình duyệt máy khách, nhưng thông qua máy chủ để tải lên máy chủ khác.
Chúng tôi sẽ thảo luận về những điều này lần lượt.
Điều kiện tiên quyết
Trước khi bắt đầu mã hóa, chúng tôi vẫn cần hiểu một số kiến thức nền tảng.
Đầu tiên, khi tải lên các tệp, chúng tôi sử dụng Axios, thư viện HTTP phổ biến nhất. Trong phát triển thực tế, chúng tôi thường không sử dụng XMLHTTPREQUEST trực tiếp và sử dụng các Axios phù hợp với mô hình phát triển thực.
Khi chúng ta thảo luận về việc tải lên các tệp ở phía trước, nếu chúng ta muốn hiểu đầy đủ các nguyên tắc có liên quan, chúng ta phải hiểu mã back-end có liên quan. Ở đây chúng tôi sử dụng KOA để triển khai máy chủ của chúng tôi.
Cuối cùng, tôi hy vọng bạn sẽ có một sự hiểu biết ngắn gọn về FormData, chúng tôi sử dụng định dạng dữ liệu này để tải lên các tệp.
Tải lên một tệp duy nhất
Sự cần thiết phải tải lên một tập tin là quá phổ biến. Ví dụ: khi bạn đăng ký phương tiện, bạn cần tải lên Avatar.
Hàm tải lên tệp yêu cầu hợp tác giữa máy khách và máy chủ. Trong dự án của chúng tôi, người dùng chọn một tệp trong máy khách và tải nó lên máy chủ; Máy chủ lưu tệp và trả về URL của nó.
Đây là bản xem trước dự án:
GIF trên hiển thị quá trình tải lên tệp đầy đủ:
- Người dùng chọn một tệp trong trình duyệt
- Người dùng nhấp vào nút tải lên
- Các tệp được tải lên được đặt trong thư mục
$ node server.js
1 của máy chủ - Sau đó, máy chủ trả về một url, là địa chỉ của tệp đã tải lên
- Người dùng có thể truy cập tài nguyên thông qua URL này
Mật mã
Tất cả các mã của dự án này đã được tổ chức trên GitHub:
Bạn có thể sao chép nó với máy tính của bạn:
# clone it
$ git clone :BytefishMedium/FileUploading.git# and install npm package
$ cd FileUloading
$ npm install
Tất cả các mã liên quan đến tải lên tệp đơn được đặt trên thư mục
$ node server.js
2.$ node server.js
3 Liên quan đến mã phía máy khách.$ node server.js
4 Liên quan đến mã phía máy chủ
Để chạy máy chủ, bạn có thể vào thư mục và chạy lệnh này:
$ node server.js
Sau đó, bạn có thể mở
$ node server.js
3 trên bất kỳ trình duyệt nào.Các hoạt động cụ thể tôi đã hiển thị trong GIF ở trên. Bạn có thể thử nó cho chính mình trước, và sau đó đọc tiếp.
Mã phía máy khách
Ừm, cần bao nhiêu bước để đặt một con hươu cao cổ vào tủ lạnh?
Chỉ ba bước:
- Mở cửa
- Đặt hươu cao cổ vào
- và đóng cửa.
Điều tương tự cũng đúng khi tải lên các tệp, chúng tôi chỉ cần ba bước:
- Cho phép người dùng chọn một tệp để tải lên
- Đọc tập tin này
- Tải lên tệp bằng Axios
Trong HTML, chúng ta có thể sử dụng phần tử
$ node server.js
6. Chỉ cần đặt loại phần tử này thành $ node server.js
7, thì phần tử có thể được sử dụng để chọn tệp.Sau khi người dùng chọn một tệp, siêu dữ liệu của tệp sẽ được lưu trữ trong thuộc tính
$ node server.js
8 của phần tử đầu vào này.const uploadFileEle = document.getElementById["fileInput"]console.log[uploadFileEle.files[0]];
Cuối cùng, chúng tôi sử dụng phương thức bài đăng Axios để tải lên các tệp. Nhưng trước khi tải lên tệp, chúng tôi cũng cần đóng gói tệp này thành định dạng FormData.
let file = fileElement.files[0];
let formData = new FormData[];
formData.set['file', file];axios.post["//localhost:3001/upload-single-file", formData]
.then[res => {
console.log[res]
}]
Mẹo: FormData là định dạng dữ liệu loại giá trị khóa. Đây là một ví dụ:
Vâng, đây là những điểm kiến thức liên quan đến tải lên tệp. Mã hoàn chỉnh hơn như sau:
Mã này thực sự là để thực hiện ba bước chúng tôi đã nói trước đây:
Nó chỉ là chúng tôi đã thêm hai chức năng bổ sung:
- Một là nút tải lên. Khi người dùng nhấp vào nút Tải lên, chúng tôi bắt đầu thực hiện logic tải lên.
- Sau đó, chúng tôi có thêm một bản án để đảm bảo rằng người dùng thực sự chọn một tệp.
Sau đó, khi Axios tải lên một tệp, nó cho phép chúng tôi giám sát tiến trình tải lên tệp.
Chúng tôi biết rằng HTTP được xây dựng trên đầu TCP. Nếu một gói HTTP tương đối lớn, nó có thể được phân tách thành nhiều gói TCP khác nhau để truyền trong mạng.
Nếu bạn cần viết một thanh tiến trình để hiển thị cho người dùng tiến trình tải lên, bạn có thể sử dụng API này.
axios.post["//localhost:3001/upload-single-file", formData, {
onUploadProgress: [progressEvent] => {
const percentCompleted = Math.round[
[progressEvent.loaded * 100] / progressEvent.total
];
console.log[`upload process: ${percentCompleted}%`];
},
}];
$ node server.js
9 có nghĩa là có bao nhiêu byte đã tải lên thành công và 0 có nghĩa là tổng số byte của tệp.
OK, đây là mã phía máy khách của chúng tôi.
Mã phía máy chủ
Để bắt đầu một máy chủ, chúng ta có thể sử dụng KOA. Đây là một máy chủ nhỏ bằng cách sử dụng KOA:
Đây là bản demo KOA cơ bản nhất. Vì bài viết này tập trung vào việc tải lên tệp, vì vậy tôi sẽ không giải thích chi tiết điều này. Nếu bạn không quen thuộc với điều này, bạn có thể đọc tài liệu chính thức.
- Koa
- Koa-router
Khách hàng của chúng tôi sử dụng định dạng formdata để tải lên các tệp, sau đó máy chủ của chúng tôi cũng cần phân tích formdata. Và Koa-Multer là một phần mềm trung gian giúp chúng tôi phân tích dữ liệu formdata:
Về Koa-Multer, bạn có thể đọc tài liệu chính thức của họ:
- Koa-multer
- MULTER
Mã chính là
1, dòng mã này có thể giúp chúng tôi phân tích dữ liệu của formdata, sau đó đặt thông tin tương ứng vào
2.
Trên thực tế, tại thời điểm này, máy chủ của chúng tôi đã có thể nhận các tệp được khách hàng tải lên, nhưng nó không lưu trữ chúng vào đĩa sau khi nhận được các tệp.
Nếu chúng tôi muốn KOA-Multer lưu tệp vào đĩa cho chúng tôi, chúng tôi có thể thêm cấu hình sau:
const storage = multer.diskStorage[{
destination: function [req, file, cb] {
cb[null, UPLOAD_DIR];
},
filename: function [req, file, cb] {
cb[null, `${file.originalname}`];
},
}];
const upload = multer[{ storage: storage }];
Mã hoàn chỉnh là
$ node server.js
4 và bạn có thể đọc trực tiếp trong kho lưu trữ mã.Biểu đồ dòng chảy hiện tại trông như thế này:
Dù sao, bạn nên tự mình thử.
Tải lên nhiều tập tin
Với nền tảng trên, chúng tôi viết mã đơn giản hơn nhiều để tải lên nhiều tệp.
Đầu tiên, chúng ta cần sửa đổi phần tử
$ node server.js
6 và thêm thuộc tính 5 vào nó.
Điều này là để nói với trình duyệt rằng bây giờ phần tử
$ node server.js
6 này sẽ cho phép người dùng chọn nhiều tệp cùng một lúc.Sau đó, sau khi người dùng chọn nhiều tệp, dữ liệu sẽ được đặt trong
7. Khi chúng tôi xây dựng
8, chúng tôi cần đi qua danh sách này và đặt tất cả các tệp vào
8.
let files = Array.from[fileElement.files];let formData = new FormData[];
files.forEach[[file] => {
formData.append["file", file];
}];
Sau đó, mã tải lên tệp không cần sửa đổi.
Đây là mã hoàn chỉnh:
Các tập tin được đặt vào
const uploadFileEle = document.getElementById["fileInput"]console.log[uploadFileEle.files[0]];0 trong dự án.
Đồng thời, chúng tôi cũng cần điều chỉnh mã ở phía máy chủ.
Đầu tiên, chúng ta cần thêm tuyến đường tương ứng
const uploadFileEle = document.getElementById["fileInput"]console.log[uploadFileEle.files[0]];1, sau đó sử dụng phần mềm trung gian
const uploadFileEle = document.getElementById["fileInput"]console.log[uploadFileEle.files[0]];2 để xử lý nhiều tệp. Sau đó, dữ liệu formdata trong
const uploadFileEle = document.getElementById["fileInput"]console.log[uploadFileEle.files[0]];3 sẽ được đặt trong
const uploadFileEle = document.getElementById["fileInput"]console.log[uploadFileEle.files[0]];4.
, and then use the
const uploadFileEle = document.getElementById["fileInput"]console.log[uploadFileEle.files[0]];2 middleware to handle multiple files. After that, the FormData data in
const uploadFileEle = document.getElementById["fileInput"]console.log[uploadFileEle.files[0]];3 will be placed in
const uploadFileEle = document.getElementById["fileInput"]console.log[uploadFileEle.files[0]];4.
Demo:
Tải lên thư mục
Bây giờ, hãy để Lôi nhìn vào các bước để tải lên một thư mục.
Tương tự như trước, chúng ta cần đặt thuộc tính của phần tử
$ node server.js
6 cho điều này:Sau đó, khi tải lên thư mục, đối tượng
$ node server.js
8 của phần tử đầu vào sẽ có thuộc tính const uploadFileEle = document.getElementById["fileInput"]console.log[uploadFileEle.files[0]];7 và chúng tôi cũng sẽ thêm chúng vào formdata
Cần lưu ý ở đây rằng khi tên tệp chứa
const uploadFileEle = document.getElementById["fileInput"]console.log[uploadFileEle.files[0]];8, KOA-Multer có thể gây ra lỗi. Để khắc phục điều này, chúng ta cần thay thế
const uploadFileEle = document.getElementById["fileInput"]console.log[uploadFileEle.files[0]];8 bằng ký hiệu
let file = fileElement.files[0];0.
let formData = new FormData[];
formData.set['file', file];axios.post["//localhost:3001/upload-single-file", formData]
.then[res => {
console.log[res]
}]
$ node server.js
0Sau đó, chúng tôi cũng cần sửa đổi mã máy chủ tương ứng:
Demo:
Sự kết luận
Chà, chúng tôi đã phân tích quá trình tải lên một tệp, nhiều tệp và thư mục lần lượt. Nó thực sự rất đơn giản, chỉ 3 bước:
- Sử dụng phần tử
$ node server.js
6 để cho người dùng chọn tệp - Đọc tệp và xây dựng formdata
- Tải lên FormData với Axios
Tất cả các mã là trên GitHub, bạn có thể tự mình thử. Nếu bạn có bất kỳ câu hỏi, bạn có thể để lại một bình luận.
Do độ dài của bài viết, phần còn lại của việc tải lên tệp sẽ được đưa vào một bài viết sau. Nếu bạn quan tâm đến nội dung này, bạn có thể theo dõi tôi.
Cảm ơn vì đã đọc.