Làm cách nào để buộc tải xuống một tệp bằng JavaScript?

Một trong những câu hỏi tôi được hỏi tương đối thường xuyên là làm thế nào để buộc một tệp tải xuống thay vì mở trực tiếp trong trình duyệt

Ví dụ: giả sử bạn có biên nhận PDF hoặc tệp MP3 mà bạn muốn cho phép mọi người tải xuống. Bạn có thể trỏ nó tới tệp đó bằng một liên kết

Download Receipt

Trong hầu hết các trình duyệt, nhấp vào liên kết sẽ mở tệp trực tiếp trong trình duyệt

Tuy nhiên, nếu bạn thêm thuộc tính download vào liên kết, nó sẽ yêu cầu trình duyệt tải xuống tệp thay thế

Download Receipt

Thuộc tính download hoạt động trong tất cả các trình duyệt hiện đại, bao gồm cả MS Edge, nhưng không phải Internet Explorer

Trong các phiên bản Chrome mới nhất, bạn không thể tải xuống các tệp có nguồn gốc chéo (chúng phải được lưu trữ trên cùng một miền)

Để tải xuống bất kỳ loại tệp nào theo cách lập trình trong JavaScript, chúng tôi có thể sử dụng một neo vô hình với thuộc tính download. Khi thuộc tính download được đặt trên một neo, nó sẽ cố tải xuống tài nguyên ở thuộc tính href 


<a href="/resources/report.pdf" download>


<a href="/resources/report.pdf" download="latest-reports.pdf">
Các neo có thuộc tính tải xuống

Đã sao chép vào khay nhớ tạm. Sao chép

Bằng cách đặt giá trị cho thuộc tính download, chúng tôi có thể chỉ định tên tùy chỉnh cho tệp đã tải xuống

Tất nhiên, khi chúng tôi muốn tạo tệp để tải xuống nhanh chóng theo chương trình, chúng tôi không có sẵn tệp đó trên máy chủ, vì vậy không có URL để trỏ neo tới. Để tạo và tải xuống tệp theo chương trình, chúng tôi có thể sử dụng URL dữ liệu

URL dữ liệu là gì

URL dữ liệu là những URL có tiền tố là sơ đồ 

data:[>][;base64],>
0 cho phép chúng tôi đưa các tệp nhỏ vào trong tài liệu. Chúng tôi sẽ sử dụng phương pháp này để tạo tài nguyên theo chương trình mà chúng tôi muốn tải xuống, trong ví dụ này là tệp JSON chứa dữ liệu cần thiết. URL dữ liệu có định dạng sau

data:[>][;base64],>
Định dạng của URL dữ liệu

Đã sao chép vào khay nhớ tạm. Sao chép

  • _
    data:[>][;base64],>
    1 là loại MIME, chẳng hạn như 
    data:[>][;base64],>
    2 hoặc 
    data:[>][;base64],>
    3. Trong trường hợp của chúng tôi, chúng tôi sẽ sử dụng 
    data:[>][;base64],>
    4 cho các tệp văn bản thuần túy. Chúng tôi cũng sẽ cần đặt mã hóa ký tự thành UTF-8 để có định dạng mã hóa chính xác
  • Có một chuỗi 
    data:[>][;base64],>
    5 tùy chọn mà chúng ta có thể đặt trong trường hợp muốn nhúng dữ liệu nhị phân được mã hóa base64. Trong trường hợp của chúng tôi, chúng tôi có thể bỏ qua giá trị này
  • Cuối cùng, chúng tôi có dữ liệu thực tế cho tệp. Để chuyển đổi dữ liệu thành chuỗi URI chính xác, chúng ta có thể sử dụng hàm 
    data:[>][;base64],>
    6 tích hợp sẵn

Điều này để lại cho chúng tôi những điều sau đây cho URL dữ liệu

'data:text/plain;charset=utf-8,' + encodeURIComponent(data)
URI dữ liệu cần thiết để xuất dữ liệu ở định dạng JSON

Đã sao chép vào khay nhớ tạm. Sao chép

Tìm cách để cải thiện kỹ năng của bạn?

Làm cách nào để buộc tải xuống một tệp bằng JavaScript?

Tự động tạo liên kết tải xuống

Để sử dụng URL dữ liệu của chúng tôi, chúng tôi cũng cần tự động tạo một liên kết. Đối với điều này, chúng ta có thể sử dụng

data:[>][;base64],>
7. Điều này sẽ tạo ra một mỏ neo cho chúng tôi, trên đó chúng tôi có thể đặt các thuộc tính hrefdownload tương ứng, sau đó nhấp vào liên kết theo chương trình để kích hoạt tải xuống. Với mọi thứ được kết hợp, chúng ta có thể sử dụng chức năng sau để tải xuống tệp JSON được tạo theo chương trình

const download = (data, filename) => {
    const data = JSON.stringify(data)
    const link = document.createElement('a')

    link.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(data))
    link.setAttribute('download', filename || 'data.json')
    link.style.display = 'none'

    document.body.appendChild(link)

    link.click()

    document.body.removeChild(link)
}

// Later call it like so:
download({ name: 'John Doe', email: '[email protected]', phone: '+1 234 567' })

// Calling with a custom file name
download({ name: 'John Doe' }, 'user.json')
tải xuống. js Tạo chức năng tải xuống để tải tệp xuống

Đã sao chép vào khay nhớ tạm. Sao chép

Hàm này chấp nhận một đối tượng JavaScript sẽ được chuyển đổi thành JSON. Nó cũng có thể tùy chọn chấp nhận tên tệp làm tham số thứ hai. Khi liên kết được tạo, chúng ta có thể đặt các thuộc tính thích hợp cho liên kết đó bằng phương thức 

'data:text/plain;charset=utf-8,' + encodeURIComponent(data)
0. Chúng tôi cũng muốn đặt thuộc tính 
'data:text/plain;charset=utf-8,' + encodeURIComponent(data)
1 của nó thành 
'data:text/plain;charset=utf-8,' + encodeURIComponent(data)
2, để ngăn liên kết hiển thị ở bất kỳ đâu trên trang

Sau khi tất cả các thuộc tính cần thiết có trên liên kết, chúng ta có thể nối phần tử đó vào tài liệu, sử dụng phương thức 

'data:text/plain;charset=utf-8,' + encodeURIComponent(data)
3 và kích hoạt nhấp chuột vào liên kết để bắt đầu tải xuống. Sau khi bắt đầu tải xuống tài nguyên, chúng tôi có thể xóa liên kết khỏi tài liệu bằng phương pháp 
'data:text/plain;charset=utf-8,' + encodeURIComponent(data)
4


Cách tải xuống các đốm màu trong JavaScript

Tuy nhiên, phương pháp trên có hạn chế. Nó không hoạt động với các tệp không dựa trên văn bản và mặc dù chúng tôi có thể thay đổi loại MIME nhưng nó cũng không hoạt động với các tệp được lưu trữ ở nơi khác. Để giải quyết vấn đề này, hãy giới thiệu cho bạn các đốm màu

Sử dụng các đốm màu là một cách tiếp cận chung hơn để tải xuống các tệp nhị phân hoặc các tệp không được tạo theo chương trình nhưng được lưu trữ ở nơi khác. Đối với điều này, chúng tôi cần sử dụng API

'data:text/plain;charset=utf-8,' + encodeURIComponent(data)
5 kết hợp với
'data:text/plain;charset=utf-8,' + encodeURIComponent(data)
6 để tạo URL chính xác cho blob, sau đó sử dụng URL này cho href. Dựa trên điều này, mã của chúng tôi thay đổi như sau

const download = async (url, filename) => {
    const data = await fetch(url)
    const blob = await data.blob()
    const objectUrl = URL.createObjectURL(blob)

    const link = document.createElement('a')

    link.setAttribute('href', objectUrl)
    link.setAttribute('download', filename)
    link.style.display = 'none'

    document.body.appendChild(link)
  
    link.click()
  
    document.body.removeChild(link)
}

// Later call it with an URL and filename like so:
download('https://unpkg.com/[email protected]/umd/react.production.min.js', 'react.js')
Tạo chức năng tải xuống để tải xuống các đốm màu

Đã sao chép vào khay nhớ tạm. Sao chép

Trong ví dụ trên, chúng tôi đang sử dụng

'data:text/plain;charset=utf-8,' + encodeURIComponent(data)
8 để tìm nạp tài nguyên tại URL được cung cấp. Sau đó, chúng ta có thể chuyển đổi kết quả trả về bằng cách sử dụng phương thức
'data:text/plain;charset=utf-8,' + encodeURIComponent(data)
9 trên đó. Cuối cùng, sau đó chúng tôi tạo URL blob thích hợp bằng cách sử dụng
'data:text/plain;charset=utf-8,' + encodeURIComponent(data)
6 dự kiến ​​một blob sẽ được chuyển cho nó

// The returned value of a blob
> Blob { size: 10737, type: 'application/javascript' }

// The returned value of a blob URL
> 'blob:http://localhost:8080/b813048a-2074-4333-ac10-0b81b9c5ca17'
Giá trị của blob và URL blob

Đã sao chép vào khay nhớ tạm. Sao chép

Tìm cách để cải thiện kỹ năng của bạn?

Làm cách nào để buộc tải xuống một tệp bằng JavaScript?

Tóm lại là

Tóm lại, chúng tôi có thể sử dụng URL dữ liệu để tải xuống các tệp được tạo động một cách nhanh chóng hoặc sử dụng API

'data:text/plain;charset=utf-8,' + encodeURIComponent(data)
5 với
'data:text/plain;charset=utf-8,' + encodeURIComponent(data)
6 để tải xuống các đốm màu và tệp từ các miền khác. Bạn cũng cần đọc lại các tệp bằng JavaScript và theo dõi tiến trình của chúng?

Làm cách nào để buộc tải xuống một tệp bằng JavaScript?

Cách mở bất kỳ tệp nào trong Javascript bằng thanh tiến trình

Sử dụng nghệ thuật văn bản ASCII trong thanh tìm kiếm của bạn
Tìm hiểu cách bạn có thể mở và đọc bất kỳ tệp nào bằng JavaScript, đồng thời hiển thị tiến trình đọc bằng nghệ thuật văn bản ASCII trong thanh tìm kiếm của bạn

Làm cách nào để kích hoạt tải xuống tệp trong JavaScript?

display = "không"; . href = URL. createObjectURL(tệp); . tải xuống = tệp. name; // Nó cần được thêm vào DOM để có thể nhấp vào tài liệu.

Làm cách nào để kích hoạt tải xuống tệp khi nhấp vào nút HTML hoặc JavaScript?

Để kích hoạt tải xuống tệp khi nhấp vào nút, chúng tôi sẽ sử dụng chức năng tùy chỉnh hoặc thuộc tính tải xuống HTML 5 . Thuộc tính tải xuống chỉ cần sử dụng thẻ neo để chuẩn bị vị trí của tệp cần tải xuống.

Làm cách nào để tải xuống tệp văn bản trong JavaScript?

Làm cách nào để tải xuống tệp từ URL trong JavaScript?

Phương pháp này đặc biệt hữu ích cho các URL tệp được tạo động. .
const download = (đường dẫn, tên tệp) => { // Tạo một liên kết mới const anchor = document. createElement('a'); . .
tìm nạp ('https. // yêu cầu. trong/api/người dùng'). .
// Chuyển đổi JSON thành chuỗi const data = JSON. .
const url = URL. .
tải xuống (url, 'người dùng. .