लिंक के बिना जावास्क्रिप्ट बूँद फ़ाइल नाम


189

जब आप इसे window.location द्वारा डाउनलोड करने के लिए बाध्य करते हैं, तो आप जावास्क्रिप्ट में एक ब्लॉब फ़ाइल का नाम कैसे सेट करते हैं?

function newFile(data) {
    var json = JSON.stringify(data);
    var blob = new Blob([json], {type: "octet/stream"});
    var url  = window.URL.createObjectURL(blob);
    window.location.assign(url);
}

उपरोक्त कोड चलाने से पृष्ठ ताज़ा किए बिना तुरंत एक फ़ाइल डाउनलोड होती है जो इस तरह दिखाई देती है:

bfefe410-8d9c-4883-86c5-d76c50a24a1d

मैं इसके बजाय फ़ाइल नाम को मेरे-डाउनलोड के रूप में सेट करना चाहता हूं

जवाबों:


311

एकमात्र तरीका जिससे मैं वाकिफ हूं, वह है FileSaver.js द्वारा उपयोग की जाने वाली ट्रिक :

  1. एक छिपा हुआ <a>टैग बनाएं ।
  2. इसकी hrefविशेषता को बूँद के URL पर सेट करें।
  3. downloadफ़ाइल नाम पर इसकी विशेषता सेट करें ।
  4. <a>टैग पर क्लिक करें ।

यहाँ एक सरल उदाहरण है ( jsfiddle ):

var saveData = (function () {
    var a = document.createElement("a");
    document.body.appendChild(a);
    a.style = "display: none";
    return function (data, fileName) {
        var json = JSON.stringify(data),
            blob = new Blob([json], {type: "octet/stream"}),
            url = window.URL.createObjectURL(blob);
        a.href = url;
        a.download = fileName;
        a.click();
        window.URL.revokeObjectURL(url);
    };
}());

var data = { x: 42, s: "hello, world", d: new Date() },
    fileName = "my-download.json";

saveData(data, fileName);

मैंने इस उदाहरण को केवल विचार को स्पष्ट करने के लिए लिखा था, इसके बजाय फाइल कोडेवर.जेएस के उत्पादन कोड का उपयोग किया।

टिप्पणियाँ

  • पुराने ब्राउज़र "डाउनलोड" विशेषता का समर्थन नहीं करते हैं, क्योंकि यह HTML5 का हिस्सा है।
  • कुछ फ़ाइल स्वरूपों को ब्राउज़र द्वारा असुरक्षित माना जाता है और डाउनलोड विफल रहता है। Txt एक्सटेंशन वाली JSON फाइल्स को सेव करना मेरे लिए काम करता है।

2
@AshBlue "डाउनलोड" विशेषता को HTML5 की आवश्यकता है। मेरा कोड सिर्फ एक उदाहरण है, आप FileSaver.js डेमो पेज भी आज़मा सकते हैं: eligrey.com/demos/FileSaver.js
kol

1
दिलचस्प है, अगर आप बार-बार इस तरह से एक txt डाउनलोड करने की कोशिश करते हैं (बार-बार jsfiddle.net पर रन बटन दबाकर), तो डाउनलोड कभी-कभी विफल हो जाता है।
kol

2
बस यह उल्लेख करना चाहता था कि यह समाधान किसी विशेष सीमा से अधिक आकार वाली फ़ाइलों के लिए काम नहीं करेगा। जैसे-> क्रोम के लिए 2 एमबी। यह आकार ब्राउज़र से ब्राउज़र में भिन्न होता है।
मनोजदामस

3
यह मेरे लिए काम नहीं करता है क्योंकि मुझे एक नए टैब में फ़ाइल खोलने की आवश्यकता है। मुझे क्रोम में एक पीडीएफ दिखाना है, लेकिन मुझे URL टूलबार में एक उपयोगकर्ता के अनुकूल नाम दिखाना होगा, और यदि उपयोगकर्ता डाउनलोड आइकन के माध्यम से डाउनलोड करना चाहता है, तो मुझे फ़ाइल में उसी उपयोगकर्ता के अनुकूल नाम डालना होगा।
एड्रियन परेडेस

1
बस जोड़ने के लिए, आपको वास्तव में काम करने के लिए शरीर को एक टैग माउंट करने की आवश्यकता नहीं है (क्रोम में अभी प्रयास किया गया है)
परे-कोड

51

मैं इंटरनेट एक्सप्लोरर (सबसे आधुनिक संस्करण, वैसे भी) के समर्थन के साथ स्वीकृत उत्तर पर विस्तार करना चाहता था, और ____ का उपयोग करके कोड को साफ करना चाहता था:

$(document).ready(function() {
    saveFile("Example.txt", "data:attachment/text", "Hello, world.");
});

function saveFile (name, type, data) {
    if (data !== null && navigator.msSaveBlob)
        return navigator.msSaveBlob(new Blob([data], { type: type }), name);
    var a = $("<a style='display: none;'/>");
    var url = window.URL.createObjectURL(new Blob([data], {type: type}));
    a.attr("href", url);
    a.attr("download", name);
    $("body").append(a);
    a[0].click();
    window.URL.revokeObjectURL(url);
    a.remove();
}

यहाँ एक उदाहरण है फिडलगॉडस्पीड


पूरी तरह से काम किया।
N8allan

1
मैंने स्वीकृत समाधान का उपयोग किया लेकिन यह फ़ायरफ़ॉक्स में काम नहीं आया! मैं अभी भी नहीं जानता कि क्यों। आपके समाधान ने फ़ायरफ़ॉक्स में काम किया। धन्यवाद।
इलाहाब

@ मेरा साहब मेरा समाधान हमेशा काम करता है;)
अलेक्जेंड्रू

27

ऊपर दिए गए समाधान के रूप में समान सिद्धांत। लेकिन मेरे पास फ़ायरफ़ॉक्स 52.0 (32 बिट) के मुद्दे थे जहां बड़ी फाइलें (> 40 एमबीटी) यादृच्छिक पदों पर काट दी जाती हैं। RevokeObjectUrl () के कॉल को पुन: शेड्यूल करना इस समस्या को हल करता है।

function saveFile(blob, filename) {
  if (window.navigator.msSaveOrOpenBlob) {
    window.navigator.msSaveOrOpenBlob(blob, filename);
  } else {
    const a = document.createElement('a');
    document.body.appendChild(a);
    const url = window.URL.createObjectURL(blob);
    a.href = url;
    a.download = filename;
    a.click();
    setTimeout(() => {
      window.URL.revokeObjectURL(url);
      document.body.removeChild(a);
    }, 0)
  }
}

jsfiddle उदाहरण


1
मैंने पाया कि यह सेटटाइमआउट () हैक एमएस एज को ठीक करता है, जहां फ़ाइल बिल्कुल भी डाउनलोड नहीं होगी। हालाँकि, केवल रिवोकऑब्जेक्टुरल () को कॉल करने की आवश्यकता है।
रसेल फिलिप्स

मैंने पाया कि "अगर (window.navigator.msSaveOrOpenBlob)" ने मेरे लिए क्या किया
जैक्स ओलिवियर

22

देर से, लेकिन जब से मैं एक ही समस्या थी मैं अपने समाधान जोड़ें:

function newFile(data, fileName) {
    var json = JSON.stringify(data);
    //IE11 support
    if (window.navigator && window.navigator.msSaveOrOpenBlob) {
        let blob = new Blob([json], {type: "application/json"});
        window.navigator.msSaveOrOpenBlob(blob, fileName);
    } else {// other browsers
        let file = new File([json], fileName, {type: "application/json"});
        let exportUrl = URL.createObjectURL(file);
        window.location.assign(exportUrl);
        URL.revokeObjectURL(exportUrl);
    }
}

5
थैंक्स @बेन। यह ठीक काम कर रहा है। कोई डोम तत्व, क्लिक इवेंट की तरह ट्रिगर करने के लिए कुछ भी नहीं। यह सिर्फ उचित विस्तार के साथ कमाल का काम करता है। लेकिन दिए गए फ़ाइल नाम पर विचार नहीं किया गया है, डाउनलोड करने के बजाय "<object_url_id> .csv" को "<myfileName> .csv"
राम बाबू एस

3
फ़ायरफ़ॉक्स में ठीक काम करने के revokeObjectURLबाद कॉल करना location.assign, लेकिन क्रोम पर डाउनलोड को तोड़ देता है।
फ्रेड

ध्यान दें कि "एज फ़ाइल निर्माता का समर्थन नहीं करता है।" संदर्भ। caniuse.com/#feat=fileapi
user1477388

यह सही उत्तर होना चाहिए। डोम ट्री में बेकार वस्तुओं को बनाने का कोई मतलब नहीं है
लुइज़ फेलिप

अब यह करता है, जनवरी '20 से
लुइज फेलिप

6
saveFileOnUserDevice = function(file){ // content: blob, name: string
        if(navigator.msSaveBlob){ // For ie and Edge
            return navigator.msSaveBlob(file.content, file.name);
        }
        else{
            let link = document.createElement('a');
            link.href = window.URL.createObjectURL(file.content);
            link.download = file.name;
            document.body.appendChild(link);
            link.dispatchEvent(new MouseEvent('click', {bubbles: true, cancelable: true, view: window}));
            link.remove();
            window.URL.revokeObjectURL(link.href);
        }
    }

क्या इसमें कोई नई विंडो खोलने का कोई तरीका है?
एनरिक अल्तुना

मुझे लगता है कि आप link.click()माउस घटना को भेजने के बजाय कॉल कर सकते हैं ।
फ्रेड

2

"कैट.jpg" के रूप में एक यूआरएल से एक बिल्ली की तस्वीर को बचाने के लिए, एक डाउनलोड बटन का कार्य उदाहरण :

HTML:

<button onclick="downloadUrl('https://i.imgur.com/AD3MbBi.jpg', 'cat.jpg')">Download</button>

जावास्क्रिप्ट:

function downloadUrl(url, filename) {
  let xhr = new XMLHttpRequest();
  xhr.open("GET", url, true);
  xhr.responseType = "blob";
  xhr.onload = function(e) {
    if (this.status == 200) {
      const blob = this.response;
      const a = document.createElement("a");
      document.body.appendChild(a);
      const blobUrl = window.URL.createObjectURL(blob);
      a.href = blobUrl;
      a.download = filename;
      a.click();
      setTimeout(() => {
        window.URL.revokeObjectURL(blobUrl);
        document.body.removeChild(a);
      }, 0);
    }
  };
  xhr.send();
}

1

window.location.assign ने मेरे लिए काम नहीं किया। यह ठीक है, लेकिन विंडोज प्लेटफॉर्म पर CSV फ़ाइल के एक्सटेंशन के बिना डाउनलोड करता है। निम्नलिखित ने मेरे लिए काम किया।

    var blob = new Blob([csvString], { type: 'text/csv' });
    //window.location.assign(window.URL.createObjectURL(blob));
    var link = window.document.createElement('a');
    link.href = window.URL.createObjectURL(blob);
    // Construct filename dynamically and set to link.download
    link.download = link.href.split('/').pop() + '.' + extension; 
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);

0

यह मेरा समाधान है। मेरे दृष्टिकोण से, आप बायपास नहीं कर सकते <a>

function export2json() {
  const data = {
    a: '111',
    b: '222',
    c: '333'
  };
  const a = document.createElement("a");
  a.href = URL.createObjectURL(
    new Blob([JSON.stringify(data, null, 2)], {
      type: "application/json"
    })
  );
  a.setAttribute("download", "data.json");
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
}
<button onclick="export2json()">Export data to json file</button>

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.