ด้วยการพัฒนาเทคโนโลยีฟรอนต์เอนด์ สถานการณ์ทางธุรกิจจำนวนมากขึ้นเรื่อยๆ จำเป็นต้องมีฟรอนต์เอนด์เพื่อจัดการการดาวน์โหลดไฟล์ ในบรรดาวิธีการต่างๆ มากมาย การดาวน์โหลดผ่านแอตทริบิวต์การดาวน์โหลดของแท็ก <a>
เป็นวิธีการทั่วไปและค่อนข้างง่าย
แท็ก <a>
download
ใช้ลิงก์ข้ามผ่าน <a>
.
download
เป็นแอตทริบิวต์ใหม่ของแท็ก <a>
ใน HTML5 คุณลักษณะนี้จะบังคับให้ดำเนินการดาวน์โหลดโดยสั่งให้เบราว์เซอร์ดาวน์โหลด URL แทนที่จะไปที่ URL และแจ้งให้ผู้ใช้บันทึกเป็นไฟล์ในเครื่อง ตัวอย่างเช่น:
<a href=result.png ดาวน์โหลด>ดาวน์โหลด</a>
หากไม่มีแอตทริบิวต์ download
การคลิกดาวน์โหลดจะเปลี่ยนเป็นรูปภาพตัวอย่างโดยตรง เมื่อเพิ่มแอตทริบิวต์ download
แล้ว การดาวน์โหลดรูปภาพจะถูกทริกเกอร์
ความเข้ากันได้ในปัจจุบันของแอตทริบิวต์ download
ดังที่แสดงใน caniuse:
จะเห็นได้ว่าโดยทั่วไปแล้วเบราว์เซอร์กระแสหลักส่วนใหญ่รองรับคุณสมบัติ download
และประสิทธิภาพของ IE ก็น่าประทับใจเช่นเคย ในปัจจุบัน ระบบ Window จำนวนมากยังคงใช้ IE ซึ่งเป็นสิ่งที่ธุรกิจจำนวนมากจำเป็นต้องพิจารณาเช่นกัน ปัญหาความเข้ากันได้นี้จำกัดการใช้งานใน download
ที่กว้างขึ้น
เมื่อต้องเผชิญกับสถานการณ์ทางธุรกิจบางประการในการดาวน์โหลดเนื้อหาแบบไดนามิก นั่นคือ ที่อยู่ของทรัพยากร เช่น รูปภาพไม่ได้รับการแก้ไข (เช่น รูปภาพที่สร้างโดยเครื่องมือวาดภาพออนไลน์บางชนิด) การใช้ HTML เท่านั้นที่ไม่สามารถตอบสนองความต้องการได้ เพื่อตอบสนองการดาวน์โหลด URL ที่แตกต่างกัน สามารถใช้วิธีการทริกเกอร์การดาวน์โหลด URL แบบไดนามิกผ่าน JS ได้
ฟังก์ชั่นดาวน์โหลด (href, filename='') { const a = document.createElement('a') a.download = ชื่อไฟล์ a.href = href document.body.appendChild(a) a.click() a.remove() }
ควรสังเกตว่าการดำเนินการ appendChild
และการ remove
ที่ดำเนินการกับ <a>
ที่สร้างขึ้นในโค้ดนั้นส่วนใหญ่เพื่อความเข้ากันได้กับเบราว์เซอร์ FireFox เมื่อเรียกใช้เมธอดนี้ภายใต้เบราว์เซอร์ FireFox หากคุณไม่เพิ่มแท็ก <a>
ที่สร้างขึ้น เนื้อความ คลิกลิงก์จะไม่ทำอะไรเลยและทริกเกอร์การดาวน์โหลด ซึ่งไม่ใช่กรณีใน Chrome
วิธีการข้างต้นสามารถดาวน์โหลดทรัพยากรที่มีต้นกำเนิดเดียวกันได้ แต่ในหลายสถานการณ์ ทรัพยากรข้ามโดเมนก็จำเป็นต้องได้รับการประมวลผลเช่นกัน ขออภัย ขณะนี้แอตทริบิวต์ download
ใช้ได้กับ URL ต้นทางเดียวกัน เท่านั้น กล่าวคือ หากที่อยู่ทรัพยากรที่จะดาวน์โหลดเป็นแบบข้ามโดเมน แอตทริบิวต์ download
จะไม่ถูกต้อง และการคลิกลิงก์จะกลายเป็นการแสดงตัวอย่างการนำทาง
ทดสอบ: คลิกเพื่อดาวน์โหลด ผลลัพธ์เป็นเพียงการแสดงตัวอย่าง และไม่สามารถดาวน์โหลดรูปภาพได้
หมายเหตุ: ก่อนหน้านี้ Chrome 65 รองรับแอตทริบิวต์ download
เพื่อทริกเกอร์การดาวน์โหลดไฟล์ข้ามโดเมน หลังจากนั้น Chrome 65 จะปฏิบัติตามนโยบายต้นทางเดียวกันอย่างเคร่งครัด และไม่สามารถทริกเกอร์การดาวน์โหลดทรัพยากรข้ามโดเมนผ่านแอตทริบิวต์ download
ได้อีกต่อไป FireFox ไม่รองรับแอตทริบิวต์ download
ของทรัพยากรข้ามโดเมน
แอตทริบิวต์ download
ไม่เพียงแต่สามารถทริกเกอร์การดาวน์โหลดเท่านั้น แต่ยังระบุชื่อไฟล์ดาวน์โหลดด้วย:
<a href=test.png download=joker.png>ดาวน์โหลด</a>
หากคำต่อท้ายของไฟล์ที่ดาวน์โหลดสอดคล้องกับไฟล์ต้นฉบับ คุณสามารถตั้งชื่อไฟล์เริ่มต้นได้:
<a href=test.png download=joker>ดาวน์โหลด</a>
ผู้เขียนเคยประสบปัญหา โดยทำให้เกิดการดาวน์โหลดทรัพยากรข้ามโดเมนผ่านแท็ก <a>
โดยพื้นฐานแล้วโค้ดจะเหมือนกับวิธี การดาวน์โหลด ที่กล่าวถึงข้างต้น ยกเว้นว่าตำแหน่งที่ตั้งค่า download
จะแตกต่างออกไปเล็กน้อย:
a.setAttribute (ดาวน์โหลด จริง)
ด้วยเหตุนี้ สถานการณ์ต่อไปนี้จึงเกิดขึ้นในเบราว์เซอร์ Chrome เวอร์ชันเก่า
ชื่อไฟล์ดาวน์โหลดกลายเป็น true
แน่นอนว่าเบราว์เซอร์จะอ่านค่าแอตทริบิวต์ download
เป็นชื่อไฟล์
หลังจากวิเคราะห์แล้ว ปัญหาข้างต้นมีสาเหตุหลักมาจาก:
1. ประการแรก ไม่ควรตั้งค่า download
เป็น true
ค่าแอตทริบิวต์ของ download
แตกต่างจาก disabled
ซึ่งเกี่ยวข้องโดยตรงกับชื่อไฟล์ และสำหรับวิธีการดาวน์โหลดแบบตอบสนองส่วนหน้าและส่วนหลังนี้ ไม่จำเป็นต้องใช้แอตทริบิวต์ download
2. Chrome เวอร์ชันก่อนหน้าไม่เพียงแต่สนับสนุนแอตทริบิวต์ download
ของทรัพยากรข้ามโดเมนเท่านั้น แต่ยังรีเซ็ตชื่อไฟล์ของทรัพยากรข้ามโดเมนผ่าน download
ด้วย ดังนั้น สถานการณ์ข้างต้นจึงเกิดขึ้น
สถานการณ์ทางธุรกิจที่ส่วนหน้าและส่วนหลังร่วมมือกันในการดาวน์โหลดไฟล์ให้เสร็จสิ้น โดยทั่วไปจะถูกนำมาใช้โดยการตั้งค่าส่วนหลังของข้อมูล Content-Disposition
ในส่วนหัวของการตอบกลับ
ในสถานการณ์ HTTP พารามิเตอร์แรกของ Content-Disposition เป็นแบบอินไลน์ (ค่าเริ่มต้น ซึ่งระบุว่าเนื้อหาข้อความในการตอบกลับจะแสดงเป็นส่วนหนึ่งของหน้าหรือทั้งหน้า) หรือไฟล์แนบ (หมายความว่าเนื้อหาข้อความ ควรดาวน์โหลดลงในเครื่อง เบราว์เซอร์ส่วนใหญ่จะนำเสนอกล่องโต้ตอบบันทึกเป็นโดยกรอกค่าของชื่อไฟล์ด้วยชื่อไฟล์ที่ดาวน์โหลดไว้ล่วงหน้า)
หากมีการตั้ง Content-Disposition
ในส่วนหัวการตอบกลับและส่วนหน้ายังเพิ่มแอตทริบิวต์ download
ให้กับแท็ก <a>
ของลิงก์ที่เกี่ยวข้อง กฎการตั้งชื่อในขณะนี้คือ:
หากแอตทริบิวต์การจัดการเนื้อหาในส่วนหัว HTTP ได้รับการกำหนดชื่อไฟล์ที่แตกต่างจากแอตทริบิวต์นี้ แอตทริบิวต์ส่วนหัว HTTP จะมีความสำคัญเหนือแอตทริบิวต์นี้
หลังการทดสอบพบว่าเมื่อ Content-Disposition
ในส่วนหัว HTTP ไม่ว่างเปล่า:
ในเบราว์เซอร์ Chrome ไม่ว่าพารามิเตอร์แรกของ Content-Disposition
ในส่วนหัว HTTP จะถูกตั้งค่าเป็น ไฟล์แนบ หรือ แบบอินไลน์ ก็ตาม download
จะไม่สามารถรีเซ็ตชื่อไฟล์ได้ตราบใดที่ตั้งชื่อไฟล์ไว้ ในทางตรงกันข้าม เมื่อชื่อไฟล์ว่างเปล่า ค่าแอตทริบิวต์ download
จะถูกตั้งค่าเป็นชื่อไฟล์ ในเบราว์เซอร์ FireFox เบราว์เซอร์จะอ่านเฉพาะค่าชื่อไฟล์ของ Content-Disposition
หากชื่อไฟล์ว่างเปล่า ชื่อไฟล์ต้นฉบับจะถูกนำไปใช้ ในขณะนี้ download
ไม่สามารถรีเซ็ตชื่อไฟล์ได้
โดยสรุป: หากไม่ได้ตั้งค่าข้อมูล Content-Disposition
ในส่วนหัวการตอบกลับ (เช่น URL ต้นทางเดียวกันซึ่งโดยทั่วไปจะค้นหาตำแหน่งทรัพยากรโดยตรง) แอตทริบิวต์ download
สามารถรีเซ็ตชื่อไฟล์ได้ หากแบ็กเอนด์ได้ตั้งชื่อไฟล์ในช่อง Content-Disposition
ค่าชื่อไฟล์จะมีผลเหนือกว่า
ฉันควรทำอย่างไรหากยังต้องการรีเซ็ตชื่อไฟล์เมื่อตั้งชื่อไฟล์ไว้ที่แบ็กเอนด์แล้ว
หยด: URL นอกจากนี้ยังมีข้อมูลเบื้องต้นเกี่ยวกับแอตทริบิวต์ download
:
แม้ว่า HTTP URL จะต้องอยู่ในจุดเริ่มต้นเดียวกัน แต่คุณสามารถใช้ blob: URL และข้อมูล: URL เพื่อให้ผู้ใช้ดาวน์โหลดเนื้อหาที่สร้างโดยใช้ JavaScript ได้ง่ายขึ้น (เช่น รูปภาพที่สร้างโดยใช้แอปพลิเคชันเว็บวาดภาพออนไลน์)
Blob
(Binary Large Object) เป็นวัตถุไบนารีขนาดใหญ่ เราไม่คุ้นเคยกับสิ่งนี้ ฐานข้อมูลบางแห่งใช้ Blob เพื่อแสดงประเภทฟิลด์ที่เก็บไฟล์ไบนารี อินเทอร์เฟซของไฟล์ยังใช้ Blob โดยสืบทอดฟังก์ชันของ Blob และขยายเพื่อรองรับไฟล์บนระบบผู้ใช้ วัตถุ Blob ถูกสร้างขึ้นโดยใช้ตัวสร้าง Blob:
Blob(blobParts[, ตัวเลือก])
var debug = {hello: world};var blob = new Blob([JSON.stringify(debug, null, 2)], {type : 'application/json'});
หากคุณต้องการดาวน์โหลดไฟล์ข้อความธรรมดาหรือสตริง JS คุณสามารถแปลงข้อมูลข้อความเป็นสตรีมไบนารี blob สร้าง Blob URL และใช้แอตทริบิวต์ download
เพื่อทำการดาวน์โหลดให้เสร็จสิ้น โค้ดมีดังนี้
const downloadText = (ข้อความ ชื่อไฟล์ = '') { const a = document.createElement('a') a.download = ชื่อไฟล์ const blob = new Blob([text], {type: 'text/plain'}) // text หมายถึงเนื้อหาข้อความหรือสตริงที่ต้องดาวน์โหลด a.href = window.URL.createObjectURL(blob) // สตริง URL ที่คล้ายกับ blob:http://localhost:8080/d3958f5c-0777-0845-9dcf-2cb28783acaf จะถูกสร้างขึ้น document.body.appendChild(a) a.click() a.remove()}
อะไรคือความแตกต่างระหว่าง Blob URL นี้กับ HTTP URL ทั่วไป?
Blob URL/Object URL เป็นโปรโตคอลหลอกที่อนุญาตให้ใช้วัตถุ Blob และ File เป็นแหล่งที่มาของ URL เช่น รูปภาพและลิงก์ดาวน์โหลดข้อมูลไบนารี
เบราว์เซอร์สร้างการอ้างอิงพิเศษไปยังวัตถุ Blob หรือ File ภายในผ่าน URL.createObjectURL()
Blob URL ที่สร้างขึ้นสามารถใช้ได้ในอินสแตนซ์เดียวของเบราว์เซอร์และในเซสชันเดียวกันเท่านั้น และวัตถุ URL นี้จะถูกนำมาใช้เมื่อ ออกจากหน้าเบราว์เซอร์
ดังนั้น Blob URL ไม่สามารถชี้ไปยังทรัพยากรเซิร์ฟเวอร์ และคุณไม่สามารถเปิดในหน้าอื่นได้ ในเวลาเดียวกัน เนื่องจากความแตกต่างในรูปแบบการเข้ารหัส Blob URL จึงใช้ทรัพยากรพื้นที่น้อยกว่าและทำงานได้ดีกว่า Data URL
Blobs มีคุณสมบัติที่มีประโยชน์มากสำหรับการพัฒนาเว็บ: การสร้าง blob URL สรุปข้อมูลไบนารี่ลงในออบเจ็กต์ Blob จากนั้นใช้ URL.createObjectURL()
เพื่อสร้าง Blob URL เนื่องจาก Blob URL นั้นเป็น URL ที่มีต้นกำเนิดเดียวกัน คุณจึงใช้ URL นี้กับ download
เพื่อแก้ไขปัญหาในการดาวน์โหลดและตั้งชื่อได้ ทรัพยากรข้ามโดเมน
Blob และ Fetch สามารถแก้ปัญหาการตั้งชื่อไฟล์ข้ามโดเมนได้: ใช้ fetch
เพื่อรับทรัพยากรข้ามโดเมน ส่งคืนออบเจ็กต์ Blob และสร้าง Blob URL และทริกเกอร์การดาวน์โหลดด้วยแอตทริบิวต์ download
ของแท็ก <a>
รหัสมีดังนี้:
ฟังก์ชั่นดาวน์โหลด (href, filename = '') { const a = document.createElement('a') a.download = ชื่อไฟล์ a.href = href document.body.appendChild(a) a.click() a.remove() }ฟังก์ชั่น downloadFile(url, filename='') { fetch(url, { headers: new Headers({ Origin: location.origin, }), mode: 'cors', }) .then(res => res.blob()) .then(blob => { const blobUrl = window.URL.createObjectURL(blob) ดาวน์โหลด(blobUrl, ชื่อไฟล์) window.URL.revoidObjectURL(blobUrl) })}
ณ จุดนี้ คลิกดาวน์โหลดอีกครั้ง และสามารถดาวน์โหลดรูปภาพข้ามโดเมนไปยังพื้นที่ท้องถิ่นได้ตามปกติ
ควรสังเกตว่าเซิร์ฟเวอร์ซึ่งเป็นที่ตั้งของทรัพยากรข้ามโดเมนจำเป็นต้องได้รับการกำหนดค่าด้วยข้อมูล Access-Control-Allow-Origin
มิฉะนั้นคุณจะได้รับข้อผิดพลาดข้ามโดเมนตัวพิมพ์ใหญ่ ตัวอย่างการกำหนดค่าส่วนหัว:
// อนุญาตให้ชื่อโดเมนใด ๆ เข้าถึงส่วนหัว ('Access-Control-Allow-Origin: *'); // ระบุชื่อโดเมนเพื่อเข้าถึงส่วนหัว ('Access-Control-Allow-Origin: https://h5.ele.me ');
วิธีนี้ยังมีข้อบกพร่องอยู่บ้าง ตัวอย่างเช่น เบราว์เซอร์จะจำกัดขนาดของข้อมูล Blob ให้ไม่เกิน 500M และจะไม่เพียงพอในแง่ของประสิทธิภาพด้วย
สรุป ในปัจจุบัน มีวิธีการดาวน์โหลดมากมายที่ส่วนหน้า และการดาวน์โหลดแอตทริบิวต์ download
ก็เป็นวิธีที่ง่ายกว่า อย่างไรก็ตาม การพิจารณาคุณลักษณะบางอย่างเหล่านี้อย่างรอบคอบก็สามารถเปิดเผยข้อมูลที่เป็นประโยชน์มากมายได้เช่นกัน download
มีความเกี่ยวข้องอย่างใกล้ชิดกับคุณสมบัติของเบราว์เซอร์ ในปัจจุบัน ความเข้ากันได้ของคุณลักษณะนี้ก็เป็นปัญหาใหญ่เช่นกัน อย่างไรก็ตาม แม้แต่เจ้าหน้าที่ของ Microsoft ก็ขอร้องให้ผู้ใช้อย่าใช้ IE อีกต่อไป ฉันเชื่อว่าปัญหาความเข้ากันได้ของ download
จะยังคงได้รับการปรับปรุงต่อไป ในอนาคตและโอกาสในการสมัครจะได้รับความนิยมมากขึ้นเรื่อยๆ
ข้างต้นคือเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการศึกษาของทุกคน ฉันหวังว่าทุกคนจะสนับสนุน VeVb Wulin Network