ใช้ HTML5 / JavaScript เพื่อสร้างและบันทึกไฟล์


317

ฉันเล่นซอกับ WebGL เมื่อเร็ว ๆ นี้และได้รับผู้อ่าน Collada ทำงาน ปัญหาคือมันค่อนข้างช้า (Collada เป็นรูปแบบ verbose มาก) ดังนั้นฉันจะเริ่มแปลงไฟล์เป็นรูปแบบที่ใช้ง่ายขึ้น (อาจเป็น JSON) ฉันมีรหัสในการแยกวิเคราะห์ไฟล์ใน JavaScript แล้วดังนั้นฉันอาจใช้เป็นผู้ส่งออกของฉันด้วยเช่นกัน! ปัญหากำลังบันทึก

ตอนนี้ฉันรู้ว่าฉันสามารถแยกไฟล์ส่งผลลัพธ์ไปยังเซิร์ฟเวอร์และให้เบราว์เซอร์ร้องขอไฟล์กลับจากเซิร์ฟเวอร์เพื่อดาวน์โหลด แต่ในความเป็นจริงแล้วเซิร์ฟเวอร์ไม่มีส่วนเกี่ยวข้องกับกระบวนการนี้ดังนั้นทำไมจึงมีส่วนร่วม ฉันมีเนื้อหาของไฟล์ที่ต้องการในหน่วยความจำแล้ว มีวิธีใดบ้างที่ฉันสามารถให้ผู้ใช้ดาวน์โหลดโดยใช้ JavaScript บริสุทธิ์? (ฉันสงสัยมัน แต่อาจถาม ... )

และชัดเจน: ฉันไม่พยายามเข้าถึงระบบไฟล์โดยที่ผู้ใช้ไม่รู้ตัว! ผู้ใช้จะให้ไฟล์ (อาจผ่านการลากและวาง) สคริปต์จะแปลงไฟล์ในหน่วยความจำและผู้ใช้จะได้รับแจ้งให้ดาวน์โหลดผลลัพธ์ ทั้งหมดนี้ควรเป็นกิจกรรม "ปลอดภัย" เท่าที่เกี่ยวข้องกับเบราว์เซอร์

[แก้ไข]:ฉันไม่ได้พูดถึงมันล่วงหน้าดังนั้นผู้โพสต์ที่ตอบว่า "Flash" นั้นถูกต้องเพียงพอ แต่ส่วนหนึ่งของสิ่งที่ฉันทำคือการพยายามเน้นสิ่งที่สามารถทำได้ด้วย HTML5 บริสุทธิ์ ... ดังนั้น Flash จึงเป็น ทันทีในกรณีของฉัน (แม้ว่ามันจะเป็นคำตอบที่ถูกต้องสมบูรณ์แบบสำหรับทุกคนที่ทำแอพพลิเคชั่นเว็บ "ของจริง") ในกรณีนี้ดูเหมือนว่าฉันจะโชคไม่ดีเว้นแต่ฉันต้องการมีส่วนร่วมกับเซิร์ฟเวอร์ ขอขอบคุณ!


8
คุณอาจจะพิจารณาเปลี่ยนคำตอบที่ได้รับการยอมรับก็น่าจะเป็นวิธีที่ HTML หมดจดในขณะนี้
Pekka

คำตอบ:


256

ตกลงสร้างข้อมูล: URI ทำเคล็ดลับให้ฉันอย่างแน่นอนขอบคุณ Matthew และ Dennkster ชี้ทางเลือกนั้นออกมา! นี่เป็นวิธีที่ฉันทำ:

1) นำเนื้อหาทั้งหมดลงในสตริงที่เรียกว่า "เนื้อหา" (เช่นการสร้างเนื้อหานั้นในขั้นต้นหรือโดยการอ่าน InnerHTML ของแท็กของหน้าเว็บที่สร้างขึ้นแล้ว)

2) สร้าง URI ของข้อมูล:

uriContent = "data:application/octet-stream," + encodeURIComponent(content);

จะมีข้อจำกัดความยาวขึ้นอยู่กับประเภทของเบราว์เซอร์เป็นต้น แต่เช่น Firefox 3.6.12 จะใช้งานได้จนถึงอย่างน้อย 256k การเข้ารหัสใน Base64 แทนการใช้ encodeURIComponent อาจทำให้สิ่งต่าง ๆ มีประสิทธิภาพมากขึ้น แต่สำหรับฉันมันก็โอเค

3) เปิดหน้าต่างใหม่และ "เปลี่ยนเส้นทาง" ไปที่ URI นี้จะแจ้งให้ทราบตำแหน่งการดาวน์โหลดของหน้าสร้าง JavaScript ของฉัน:

newWindow = window.open(uriContent, 'neuesDokument');

แค่นั้นแหละ.


34
หากคุณต้องการหลีกเลี่ยงการใช้ป๊อปอัปซึ่งสามารถบล็อกได้คุณสามารถตั้งค่าlocation.hrefเป็นเนื้อหาได้ location.href = uriContent.
Alex Turpin

12
สวัสดีฉันลองสิ่งนี้ แต่มันดาวน์โหลดไฟล์เป็นไฟล์. part ฉันจะตั้งค่าประเภทไฟล์ได้อย่างไร
Sedat Başar

6
@ SedatBaşar Data URIs ไม่สนับสนุนการตั้งค่าชื่อไฟล์คุณต้องพึ่งพาการตั้งค่าเบราว์เซอร์ของนามสกุลที่เหมาะสมโดยใช้ประเภท mime แต่ถ้าเบราว์เซอร์ประเภท mime สามารถแสดงผลได้โดยเบราว์เซอร์มันจะไม่ดาวน์โหลด แต่มันจะแสดง มีวิธีอื่นในการทำเช่นนี้ แต่ไม่ทำงานใน IE <10
panzi

7
IE ไม่สนับสนุนข้อมูล URIs จริงๆและ Firefox ดูเหมือนว่าจะบันทึกไฟล์ด้วยชื่อแบบสุ่ม
nylund

25
ฉันคิดว่าเรากำลังทำสิ่งนี้ยากกว่าที่คิด เปิดคอนโซล JS ของคุณในหน้านี้แล้ววางไว้location.href = "data:application/octet-stream," + encodeURIComponent(jQuery('#answer-4551467 .post-text').first().text());และมันจะบันทึกเนื้อหาของ @ Nøkคำตอบลงในไฟล์ ฉันไม่มี IE เพื่อทดสอบ แต่ใช้งานได้กับ webkit
Bruno Bronosky

278

ทางออกที่ง่ายสำหรับเบราว์เซอร์ที่พร้อมใช้ HTML5 ...

function download(filename, text) {
    var pom = document.createElement('a');
    pom.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
    pom.setAttribute('download', filename);

    if (document.createEvent) {
        var event = document.createEvent('MouseEvents');
        event.initEvent('click', true, true);
        pom.dispatchEvent(event);
    }
    else {
        pom.click();
    }
}

การใช้

download('test.txt', 'Hello world!');

2
หากคุณทราบ URL แหล่งที่คุณต้องการดาวน์โหลดนี่เป็นทางออกที่ดีที่สุด!
sidonaldson

31
ความสามารถในการตั้งชื่อไฟล์ทำให้เป็นผู้ชนะ
Omn

9
วิธีนี้ใช้ได้กับ Chrome จนกระทั่งอัปเดตล่าสุดที่ฉันได้รับเมื่อไม่กี่วันที่ผ่านมา (35.0.1916.114 m) ตอนนี้ก็ทำงานในส่วนที่ชื่อไฟล์และนามสกุลไม่ทำงาน (มันเสมอชื่อ download.txt ไฟล์โดยไม่คำนึงถึงสิ่งที่ผ่านไป.)
Sevin7

6
ฉันมี Chrom 42.0.2311.90 และนี่ใช้งานได้กับชื่อไฟล์ที่คาดหวัง
Saurabh Kumar

4
หากมีข้อ จำกัด เกี่ยวกับปริมาณข้อมูลที่สามารถรวมได้?
Kaspar Lee

80

HTML5 กำหนดwindow.saveAs(blob, filename)วิธีการ เบราว์เซอร์ใด ๆ ไม่รองรับในขณะนี้ แต่มีไลบรารีความเข้ากันได้ที่เรียกว่าFileSaver.jsซึ่งเพิ่มฟังก์ชันนี้ในเบราว์เซอร์ที่ทันสมัยที่สุด (รวมถึง Internet Explorer 10+) Internet Explorer 10 รองรับnavigator.msSaveBlob(blob, filename)เมธอด ( MSDN ) ซึ่งใช้ใน FileSaver.js สำหรับการสนับสนุน Internet Explorer

ฉันเขียนบล็อกโพสต์พร้อมรายละเอียดเพิ่มเติมเกี่ยวกับปัญหานี้


1
สิ่งที่เกี่ยวกับการปิดกั้นป๊อปอัป? พฤติกรรมของห้องสมุดนี้คล้ายกับวิธีแก้ปัญหาของ @ Nøk ข้อความล้วนใน Firefox เปิดขึ้นมาใหม่ Chrome เท่านั้นที่พยายามบันทึก แต่เปลี่ยนส่วนขยาย (ฉันต้องการ dotfile ที่ไม่มีส่วนขยาย)
ciembor

1
@ciembor ชุดตัวแปรการดาวน์โหลด (ออบเจ็กต์ url +) (ซึ่งฉันใช้กับโครเมี่ยม) ช่วยให้คุณตั้งชื่อไฟล์ได้ มันทำงานได้ดีสำหรับฉันในโครเมี่ยม
panzi

1
@ciembor aha และป๊อปอัปไม่ได้ถูกบล็อกหากการคลิกเกิดขึ้นโดยตรง
panzi

6
FileSaver.js รองรับ IE ตอนนี้
Eli Gray

15
W3C พูดว่า: งานในเอกสารนี้ถูกยกเลิกและไม่ควรอ้างอิงหรือใช้เป็นพื้นฐานสำหรับการใช้งาน
WaiKit Kung

48

กำลังบันทึกไฟล์ขนาดใหญ่

URI ข้อมูลที่ยาวสามารถให้ปัญหาประสิทธิภาพในเบราว์เซอร์ ตัวเลือกในการบันทึกฝั่งไคลเอ็นต์ไฟล์ที่สร้างขึ้นอีกคือการใส่เนื้อหาของพวกเขาในหยด (หรือ File) URL.createObjectURL(blob)วัตถุและสร้างการเชื่อมโยงดาวน์โหลดโดยใช้ ส่งคืน URL ที่สามารถใช้เพื่อดึงเนื้อหาของหยด Blob จะถูกเก็บไว้ในเบราว์เซอร์จนกว่าจะURL.revokeObjectURL()ถูกเรียกใช้บน URL หรือเอกสารที่สร้างขึ้นจะถูกปิด เว็บเบราว์เซอร์ส่วนใหญ่มีการรองรับ URL วัตถุ , Opera Mini เป็นเว็บเดียวที่ไม่รองรับ

บังคับให้ดาวน์โหลด

หากข้อมูลเป็นข้อความหรือรูปภาพเบราว์เซอร์สามารถเปิดไฟล์ได้แทนที่จะบันทึกลงดิสก์ หากต้องการดาวน์โหลดไฟล์เมื่อคลิกที่ลิงก์คุณสามารถใช้แอdownloadททริบิวต์ได้ แต่ไม่ทุกเว็บเบราเซอร์ที่มีการสนับสนุนสำหรับแอตทริบิวต์ดาวน์โหลด ตัวเลือกอื่นคือใช้application/octet-streamเป็นไฟล์ mime-type แต่สิ่งนี้ทำให้ไฟล์ถูกแสดงในรูปแบบไบนารี blob ซึ่งโดยเฉพาะผู้ใช้ที่ไม่เป็นมิตรหากคุณไม่ระบุหรือไม่สามารถระบุชื่อไฟล์ได้ ดูเพิ่มเติมที่ " บังคับให้เปิดป๊อปอัป" บันทึกเป็น ... "ที่ลิงก์ข้อความคลิกสำหรับ PDF ใน HTML '

การระบุชื่อไฟล์

ถ้าหยดถูกสร้างขึ้นด้วยตัวสร้างไฟล์คุณยังสามารถตั้งชื่อไฟล์ แต่เว็บเบราเซอร์เพียงไม่กี่ (รวมทั้ง Chrome และ Firefox) มีการสนับสนุนสำหรับตัวสร้างไฟล์ ชื่อไฟล์สามารถระบุได้ว่าเป็นอาร์กิวเมนต์ของแอdownloadททริบิวต์ แต่สิ่งนี้อยู่ภายใต้ข้อควรพิจารณาด้านความปลอดภัยมากมาย Internet Explorer 10 และ 11 มีวิธีการของตนเองคือmsSaveBlobเพื่อระบุชื่อไฟล์

รหัสตัวอย่าง

var file;
var data = [];
data.push("This is a test\n");
data.push("Of creating a file\n");
data.push("In a browser\n");
var properties = {type: 'text/plain'}; // Specify the file's mime-type.
try {
  // Specify the filename using the File constructor, but ...
  file = new File(data, "file.txt", properties);
} catch (e) {
  // ... fall back to the Blob constructor if that isn't supported.
  file = new Blob(data, properties);
}
var url = URL.createObjectURL(file);
document.getElementById('link').href = url;
<a id="link" target="_blank" download="file.txt">Download</a>


1
ฉันสามารถแสดงไดอะล็อก (ป๊อปอัพ) เพื่อระบุโฟลเดอร์ (ไดเรกทอรี) เพื่อบันทึกไฟล์ได้หรือไม่?
Calvin

@Calvin: ฉันได้อัปเดตคำตอบเพื่ออธิบายวิธีบังคับให้ดาวน์โหลดและระบุชื่อไฟล์ สำหรับ IE ฉันเชื่อว่าคุณสามารถใช้msSaveBlobเพื่อเปิดกล่องโต้ตอบ "บันทึกเป็น" สำหรับเบราว์เซอร์อื่นตัวเลือกเดียวของคุณคือเลือก "บันทึกเป็น" ด้วยตนเองจากเมนูบริบทของลิงค์ดาวน์โหลด
bcmpinc

1
@ Jek-fdrv: เฉพาะ Blob-urls ที่ทำงานใน Safari แอตทริบิวต์การดาวน์โหลดและตัวสร้างไฟล์ไม่ได้รับการสนับสนุนโดย Safari ดังนั้นคุณจึงไม่สามารถบังคับให้ดาวน์โหลดได้หมายความว่าอาจมีการเปิด blob ในเบราว์เซอร์เองและคุณไม่สามารถระบุชื่อไฟล์ได้ ตัวอย่างที่ให้มาคุณควรจะสามารถดาวน์โหลดไฟล์ด้วย Safari โดยใช้เมนูบริบทของลิงค์
bcmpinc


นี่เป็นคำตอบที่เป็นประโยชน์และให้ข้อมูลมาก อีกสิ่งหนึ่งที่อาจช่วยให้คนอย่างฉัน: หลังจากตั้งค่าdocument.getElementById('link').href = url;รหัสของคุณสามารถไปข้างหน้าและไฟลิงค์โดยใช้.click()วิธีการขององค์ประกอบ
LarsH

36
function download(content, filename, contentType)
{
    if(!contentType) contentType = 'application/octet-stream';
        var a = document.createElement('a');
        var blob = new Blob([content], {'type':contentType});
        a.href = window.URL.createObjectURL(blob);
        a.download = filename;
        a.click();
}

3
contentType มีผลอย่างไร ใช้ทำอะไร?
Uri

3
อันนี้ทำงานได้ดีแม้ใน Chrome ล่าสุดซึ่งแตกต่างจากคำตอบของ @ MatějPokorný ขอบคุณ
Alexander Amelkin

2
สิ่งนี้ใช้ไม่ได้กับ FF36 หรือ IE11 หากฉันแทนที่a.clickด้วยรหัสโดยใช้document.createEvent()ตามที่แนะนำMatějPokornýมันจะทำงานบน FF แต่ไม่ใช่ IE ฉันยังไม่ได้ลอง Chrome
Peter Hull

25

ลองดูที่ดั๊ก Neiner ของDownloadifyซึ่งเป็นอินเตอร์เฟซที่ใช้ JavaScript แฟลชที่ใช้ในการทำเช่นนี้

Downloadify เป็นไลบรารี JavaScript + Flash ขนาดเล็กที่เปิดใช้งานการสร้างและบันทึกไฟล์ได้ทันทีในเบราว์เซอร์โดยไม่ต้องมีการโต้ตอบกับเซิร์ฟเวอร์


6
สำหรับคนส่วนใหญ่นี่อาจเป็นคำตอบที่พวกเขาต้องการ ดังนั้นแม้ว่าจะไม่เป็นไปตามข้อกำหนดเฉพาะของฉัน (ตามที่อธิบายไว้ข้างต้น) ฉันกำลังทำเครื่องหมายเป็นคำตอบที่ยอมรับได้
Toji

2
@ โทจิอาฉันเข้าใจแล้ว อาจจะถามซ้ำและเติมวลีภายใต้HTML 5แบนเนอร์และติดแท็กใหม่ ที่น่าจะดึงดูดผู้ใช้ที่รู้เกี่ยวกับฟิลด์เฉพาะนั้น (ยังคงเป็นฝูงชนขนาดเล็กเมื่อเทียบกับตอนนี้ฉันคิดว่า) ฉันค่อนข้างแน่ใจว่ามันสามารถทำได้ใน HTML 5 แต่ฉันไม่รู้ว่าอย่างไร
Pekka

1
มีdownloadify.infoโดเมน Downloadify รับการสั่งซื้อ / โอนและถ้าเป็นเช่นนั้นจะมีสถานที่ใหม่ได้หรือไม่ เว็บไซต์ปัจจุบันดูเหมือนว่าไม่เกี่ยวข้องกับคำตอบที่ได้รับอย่างสมบูรณ์
Christos Hayward

17
สิ่งนี้ไม่ตอบคำถามการใช้ HTML5 ... - ชื่อ
Ixx

5
@ ฉันดีที่จะเป็นธรรมที่ถูกเพิ่มหลังจากคำตอบที่โพสต์ ยังคุณพูดถูก คำตอบด้านล่างควรได้รับการยอมรับ
Pekka

17

ทางออกที่ง่าย!

<a download="My-FileName.txt" href="data:application/octet-stream,HELLO-WORLDDDDDDDD">Click here</a>

ใช้งานได้ในเบราว์เซอร์สมัยใหม่ทั้งหมด


สวัสดีคุณรู้วิธีระบุลักษณะการทำงานของแอตทริบิวต์ "ดาวน์โหลด" โดยใช้ window.open หรือฟังก์ชัน javascript อื่นหรือไม่
yucer

2
@yucer ไม่มีดาวน์โหลดแอตทริบิวต์ (หรือแอตทริบิวต์ใด ๆ สำหรับเรื่องที่) window.open()ด้วยคือ มันไม่เกี่ยวข้อง คุณสามารถใช้วิธีการนี้และบังคับให้.click()มัน แต่ดูเวลาเป็น Firefox ไม่ชอบถ้าคุณโทร.click()ก่อนที่จะปล่อยให้องค์ประกอบที่แนบมากับร่างกาย
แบรด

แต่น่าเสียดายที่ช่องว่างทั้งหมดถูกลบไป ในกรณีของฉันมันแย่จริง ๆ ตั้งแต่ฉันต้องการดาวน์โหลดซอร์สโค้ดสำหรับไฟล์ SVG
frankenapps

ช่องว่างจะถูกเก็บไว้หากคุณใช้ encodeURIComponent (เนื้อหา)
Mike Redrobe

ไม่สามารถเลือกชื่อใน firefox แต่งานของ chrome
Bhikkhu Subhuti

10

คุณสามารถสร้างข้อมูล URI อย่างไรก็ตามมีข้อ จำกัด เฉพาะสำหรับเบราว์เซอร์


1
สิ่งนี้น่าสนใจ ฉันจะตรวจสอบเพิ่มเติมเมื่อมีโอกาส ขอบคุณ!
Toji

@quantumpotato จริง ๆ แล้วการสร้าง URL นั้นยุ่งยากเล็กน้อยในการอธิบาย ทั้งหมดพ่อหนุ่มอยู่ในRFC 2397 คุณสามารถใช้เครื่องมือเช่นนี้เพื่อทดสอบ จากนั้นสำหรับแอปจริงของคุณคุณสามารถค้นหา data URI หรือ base 64 library สำหรับภาษาของคุณ หากคุณหาไม่พบอย่าลังเลที่จะถามคำถามติดตามผล บางส่วนของข้อ จำกัด ของเบราว์เซอร์ที่เฉพาะเจาะจงจะได้รับในวิกิพีเดียบทความ ตัวอย่างเช่น IE จำกัดความยาวและประเภท (เช่นไม่ใช่ text / html)
Matthew Flaschen

การสร้าง URL ข้อมูลนั้นไม่ยุ่งยาก: "data:text/plain;charset=UTF-8,"+encodeURIComponent(text)แต่ใช่ IE จำกัด ขนาดของ data URLs ไว้ที่จำนวนที่ไม่สามารถใช้งานได้และมันไม่รองรับพวกมันสำหรับสิ่งต่าง ๆ เช่นwindow.open(...)iframe (ฉันคิดว่า)
panzi

@panzi มันไม่ง่ายอย่างที่คิด สำหรับสิ่งหนึ่งนั่นไม่ใช่ประเภท MIME ที่เหมาะสมสำหรับ Collada หรือ JSON
Matthew Flaschen

คำตอบที่ไม่ให้ข้อมูลเกินไป กรุณาเพิ่มข้อกำหนดสำหรับเบราว์เซอร์ถ้าคุณพูดถึงพวกเขา
T.Todua

10

ฉันใช้ FileSaver ( https://github.com/eligrey/FileSaver.js ) และใช้งานได้ดี
ตัวอย่างเช่นฉันใช้ฟังก์ชันนี้เพื่อส่งออกบันทึกที่แสดงบนหน้าเว็บ
คุณต้องผ่านอาร์เรย์สำหรับการติดตั้ง Blob ดังนั้นฉันอาจจะไม่ได้เขียนสิ่งที่ถูกต้อง แต่มันได้ผลสำหรับฉัน
ในกรณีที่ต้องระมัดระวังกับการแทนที่: นี่คือไวยากรณ์ที่จะทำให้โลกนี้มิฉะนั้นมันจะแทนที่คนแรกที่เขาพบ

exportLogs : function(){
    var array = new Array();

    var str = $('#logs').html();
    array[0] = str.replace(/<br>/g, '\n\t');

    var blob = new Blob(array, {type: "text/plain;charset=utf-8"});
    saveAs(blob, "example.log");
}

2
FileSaver ยอดเยี่ยมนี่คือ Shim Shim สำหรับฟังก์ชั่น pre-IE10 preIE10SaveAs: (ชื่อไฟล์, ไฟล์เนื้อหา, mimetype) {var w = window.open (); var doc = w.document; doc.open (ชนิดย่อย 'แทนที่'); doc.charset = "utf-8"; doc.write (filecontent); doc.close (); doc.execCommand ("SaveAs", null, ชื่อไฟล์); }
aqm

คำเตือนเกี่ยวกับชิมของ @ aqm: มันรันแท็กสคริปต์
GameFreak

นอกจากนี้อาจเป็นที่พึงปรารถนาที่จะใส่w.close();หลังจากexecCommand
GameFreak

8

ฉันพบวิธีง่าย ๆ สองวิธีที่เหมาะกับฉัน ขั้นแรกให้ใช้aองค์ประกอบที่คลิกไปแล้วและทำการฉีดข้อมูลดาวน์โหลด และประการที่สองสร้างaองค์ประกอบด้วยข้อมูลดาวน์โหลดเรียกใช้งานa.click()และลบองค์ประกอบอีกครั้ง แต่วิธีที่สองใช้งานได้ก็ต่อเมื่อมีการเรียกใช้โดยการคลิกของผู้ใช้เช่นกัน (บาง) บล็อกเบราว์เซอร์click()จากบริบทอื่น ๆ เช่นเมื่อโหลดหรือถูกเรียกหลังจากหมดเวลา (setTimeout)

<!DOCTYPE HTML>
<html>
  <head>
    <meta charset="UTF-8">
    <script type="text/javascript">
      function linkDownload(a, filename, content) {
        contentType =  'data:application/octet-stream,';
        uriContent = contentType + encodeURIComponent(content);
        a.setAttribute('href', uriContent);
        a.setAttribute('download', filename);
      }
      function download(filename, content) {
        var a = document.createElement('a');
        linkDownload(a, filename, content);
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
      }
    </script>
   </head>
  <body>
    <a href="#" onclick="linkDownload(this, 'test.txt', 'Hello World!');">download</a>
    <button onclick="download('test.txt', 'Hello World!');">download</button>
  </body>
</html>

2
คุณสามารถแทรกaลงในเอกสาร (อาจเป็นด้วย"display:none") คลิกมันแล้วลบออก
Teepeemm

1
จะทำงานในเบราว์เซอร์ที่ไม่รองรับคุณสมบัติการดาวน์โหลดเช่นสมัยใหม่และซาฟารี .. caniuse.com/#feat=download
Muhammad Umer

1
เพิ่งทดสอบ Safari 5.0 ภายใต้ไวน์ รุ่นแรกใช้งานได้อันดับที่สองไม่ใช่ ฉันทดสอบ IE 8 (ไวน์) ด้วยและไม่ทำงาน
maikel

6

นี่คือลิงค์ไปยังวิธีการข้อมูล URI ที่แนะนำให้ Mathew มันทำงานบนซาฟารี แต่ไม่ดีเพราะฉันไม่สามารถตั้งไฟล์ประเภทมันได้รับการบันทึกเป็น "ไม่รู้จัก" จากนั้นฉันต้องไปที่นั่นอีกครั้งในภายหลังและเปลี่ยนตามลำดับ เพื่อดูไฟล์ ...

http://www.nihilogic.dk/labs/canvas2image/


4

คุณสามารถใช้ localStorage นี่คือ Html5 เทียบเท่ากับคุกกี้ ดูเหมือนว่าจะทำงานบน Chrome และ Firefox แต่บน Firefox ฉันต้องอัปโหลดไปยังเซิร์ฟเวอร์ นั่นคือการทดสอบโดยตรงบนคอมพิวเตอร์ที่บ้านของฉันไม่ทำงาน

ฉันกำลังทำงานตัวอย่าง HTML5 ไปที่http://faculty.purchase.edu/jeanine.meyer/html5/html5explain.html และเลื่อนไปที่เขาวงกต ข้อมูลที่จะสร้างเขาวงกตอีกครั้งจะถูกเก็บไว้โดยใช้ localStorage

ฉันมาที่บทความนี้เพื่อค้นหา HTML5 JavaScript สำหรับการโหลดและทำงานกับไฟล์ xml มันเหมือนกับ html และ JavaScript ที่เก่ากว่าหรือไม่?


4

ลอง

let a = document.createElement('a');
a.href = "data:application/octet-stream,"+encodeURIComponent('"My DATA"');
a.download = 'myFile.json';
a.click(); // we not add 'a' to DOM so no need to remove

หากคุณต้องการดาวน์โหลดข้อมูลไบนารีดูที่นี่

ปรับปรุง

2020.06.14 ฉันอัปเกรด Chrome เป็น 83.0 และสูงกว่าเพื่อให้ข้อมูลโค้ดหยุดทำงาน (เนื่องจากข้อ จำกัดด้านความปลอดภัยของ Sandbox ) - แต่เวอร์ชัน JSFiddle ใช้งานได้ - ที่นี่


3

ดังที่ได้กล่าวไปแล้วก่อนหน้านี้API ไฟล์พร้อมกับFileWriterและFileSystem APIs สามารถใช้ในการจัดเก็บไฟล์บนเครื่องของลูกค้าจากบริบทของแท็บ / หน้าต่างเบราว์เซอร์

อย่างไรก็ตามมีหลายสิ่งที่เกี่ยวข้องกับสอง API หลังซึ่งคุณควรระวัง:

  • ปัจจุบันการติดตั้ง API นั้นมีอยู่เฉพาะในเบราว์เซอร์ที่ใช้ Chromium (Chrome & Opera)
  • API ทั้งสองตัวถูกนำออกจากแทร็กมาตรฐาน W3C เมื่อวันที่ 24 เมษายน 2014 และ ณ ตอนนี้เป็นกรรมสิทธิ์
  • การลบ APIs (ปัจจุบันเป็นกรรมสิทธิ์) จากการใช้เบราว์เซอร์ในอนาคตเป็นไปได้
  • Sandbox (สถานที่ด้านนอกของดิสก์ไฟล์ที่สามารถผลิตไม่มีผล) ถูกนำมาใช้ในการจัดเก็บไฟล์ที่สร้างขึ้นด้วย API จะ
  • ระบบแฟ้มเสมือน (โครงสร้างไดเรกทอรีที่ไม่จำเป็นต้องอยู่บนดิสก์ในรูปแบบเดียวกับที่มันไม่เมื่อเข้าถึงได้จากภายในเบราว์เซอร์) จะใช้แทนไฟล์ที่สร้างขึ้นด้วย API จะ

นี่คือตัวอย่างง่ายๆของวิธีการใช้ API ทั้งทางตรงและทางอ้อมเพื่อทำสิ่งนี้:

BakedGoods *

bakedGoods.get({
        data: ["testFile"],
        storageTypes: ["fileSystem"],
        options: {fileSystem:{storageType: Window.PERSISTENT}},
        complete: function(resultDataObj, byStorageTypeErrorObj){}
});

การใช้ไฟล์ raw, FileWriter และ FileSystem API

function onQuotaRequestSuccess(grantedQuota)
{

    function saveFile(directoryEntry)
    {

        function createFileWriter(fileEntry)
        {

            function write(fileWriter)
            {
                var dataBlob = new Blob(["Hello world!"], {type: "text/plain"});
                fileWriter.write(dataBlob);              
            }

            fileEntry.createWriter(write);
        }

        directoryEntry.getFile(
            "testFile", 
            {create: true, exclusive: true},
            createFileWriter
        );
    }

    requestFileSystem(Window.PERSISTENT, grantedQuota, saveFile);
}

var desiredQuota = 1024 * 1024 * 1024;
var quotaManagementObj = navigator.webkitPersistentStorage;
quotaManagementObj.requestQuota(desiredQuota, onQuotaRequestSuccess);

แม้ว่า FileSystem และ FileWriter APIs จะไม่อยู่ในแทร็กมาตรฐานอีกต่อไปการใช้งานของพวกเขาสามารถพิสูจน์ได้ในบางกรณีในความคิดของฉันเพราะ:

  • ความสนใจที่ต่ออายุใหม่จากผู้ขายเบราว์เซอร์ที่ไม่ใช้งานอาจทำให้พวกเขากลับมาได้ทันที
  • ส่วนแบ่งการตลาดของการใช้เบราว์เซอร์
  • Google (ผู้สนับสนุนหลักของ Chromium) ยังไม่ได้ให้และวันที่สิ้นสุดของ API

ไม่ว่า "บางกรณี" จะรวมอยู่ในตัวคุณเองหรือไม่

* BakedGoods ดูแลโดยไม่มีใครอื่นนอกจากเจ้านี่ตรงนี้ :)


2

เธรดนี้มีค่ายิ่งในการหาวิธีสร้างไฟล์ไบนารีและแจ้งให้ดาวน์โหลดไฟล์ที่ระบุชื่อทั้งหมดในรหัสลูกค้าที่ไม่มีเซิร์ฟเวอร์

ขั้นตอนแรกสำหรับฉันคือการสร้างไบนารีหยดจากข้อมูลที่ฉันบันทึกไว้ มีตัวอย่างมากมายสำหรับการทำสิ่งนี้สำหรับประเภทไบนารีเดียวในกรณีของฉันฉันมีรูปแบบไบนารีที่มีหลายประเภทซึ่งคุณสามารถผ่านเป็นอาร์เรย์เพื่อสร้างหยด

saveAnimation: function() {

    var device = this.Device;
    var maxRow = ChromaAnimation.getMaxRow(device);
    var maxColumn = ChromaAnimation.getMaxColumn(device);
    var frames = this.Frames;
    var frameCount = frames.length;

    var writeArrays = [];


    var writeArray = new Uint32Array(1);
    var version = 1;
    writeArray[0] = version;
    writeArrays.push(writeArray.buffer);
    //console.log('version:', version);


    var writeArray = new Uint8Array(1);
    var deviceType = this.DeviceType;
    writeArray[0] = deviceType;
    writeArrays.push(writeArray.buffer);
    //console.log('deviceType:', deviceType);


    var writeArray = new Uint8Array(1);
    writeArray[0] = device;
    writeArrays.push(writeArray.buffer);
    //console.log('device:', device);


    var writeArray = new Uint32Array(1);
    writeArray[0] = frameCount;
    writeArrays.push(writeArray.buffer);
    //console.log('frameCount:', frameCount);

    for (var index = 0; index < frameCount; ++index) {

      var frame = frames[index];

      var writeArray = new Float32Array(1);
      var duration = frame.Duration;
      if (duration < 0.033) {
        duration = 0.033;
      }
      writeArray[0] = duration;
      writeArrays.push(writeArray.buffer);

      //console.log('Frame', index, 'duration', duration);

      var writeArray = new Uint32Array(maxRow * maxColumn);
      for (var i = 0; i < maxRow; ++i) {
        for (var j = 0; j < maxColumn; ++j) {
          var color = frame.Colors[i][j];
          writeArray[i * maxColumn + j] = color;
        }
      }
      writeArrays.push(writeArray.buffer);
    }

    var blob = new Blob(writeArrays, {type: 'application/octet-stream'});

    return blob;
}

ขั้นตอนต่อไปคือการให้เบราว์เซอร์แจ้งผู้ใช้ให้ดาวน์โหลดหยดนี้ด้วยชื่อที่กำหนดไว้ล่วงหน้า

สิ่งที่ฉันต้องการคือลิงค์ชื่อที่ฉันเพิ่มใน HTML5 ที่ฉันสามารถนำมาใช้ใหม่เพื่อเปลี่ยนชื่อไฟล์เริ่มต้น ฉันซ่อนมันไว้เนื่องจากลิงค์ไม่ต้องการแสดง

<a id="lnkDownload" style="display: none" download="client.chroma" href="" target="_blank"></a>

ขั้นตอนสุดท้ายคือแจ้งให้ผู้ใช้ดาวน์โหลดไฟล์

var data = animation.saveAnimation();
var uriContent = URL.createObjectURL(data);
var lnkDownload = document.getElementById('lnkDownload');
lnkDownload.download = 'theDefaultFileName.extension';
lnkDownload.href = uriContent;
lnkDownload.click();

1

นี่คือบทช่วยสอนเพื่อส่งออกไฟล์เป็น ZIP:

ก่อนเริ่มต้นใช้งานมีไลบรารีสำหรับบันทึกไฟล์ชื่อของไลบรารีคือ fileSaver.js คุณสามารถค้นหาไลบรารีนี้ได้ที่นี่ มาเริ่มกันเลยตอนนี้รวมไลบรารี่ที่ต้องการแล้ว:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.4/jszip.min.js"  type="text/javascript"></script>
<script type="text/javascript" src="https://fastcdn.org/FileSaver.js/1.1.20151003/FileSaver.js" ></script>

ตอนนี้คัดลอกรหัสนี้และรหัสนี้จะดาวน์โหลดไฟล์ zip พร้อมไฟล์ hello.txt ที่มีเนื้อหา Hello World หากทุกอย่างทำงานได้ดีจะเป็นการดาวน์โหลดไฟล์

<script type="text/javascript">
    var zip = new JSZip();
    zip.file("Hello.txt", "Hello World\n");
    zip.generateAsync({type:"blob"})
    .then(function(content) {
        // see FileSaver.js
        saveAs(content, "file.zip");
    });
</script>

นี่จะดาวน์โหลดไฟล์ชื่อ file.zip คุณสามารถอ่านเพิ่มเติมได้ที่นี่: http://www.wapgee.com/story/248/guide-to-create-zip-files-using-javascript-by-using-jszip-library

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.