ब्राउज़र से फाइल के रूप में JSON ऑब्जेक्ट डाउनलोड करें


144

मेरे पास csv फ़ाइल में डेटा स्ट्रिंग्स को डाउनलोड करने के लिए निम्नलिखित कोड हैं।

exportData = 'data:text/csv;charset=utf-8,';
exportData += 'some csv strings';
encodedUri = encodeURI(exportData);
newWindow = window.open(encodedUri);

यह ठीक काम करता है कि यदि क्लाइंट कोड चलाता है तो यह खाली पेज उत्पन्न करता है और सीएसवी फ़ाइल में डेटा डाउनलोड करना शुरू करता है।

इसलिए मैंने JSON ऑब्जेक्ट के साथ ऐसा करने की कोशिश की

exportData = 'data:text/json;charset=utf-8,';
exportData += escape(JSON.stringify(jsonObject));
encodedUri = encodeURI(exportData);
newWindow = window.open(encodedUri);

लेकिन मुझे केवल JSON डेटा के साथ एक पृष्ठ दिखाई देता है, इसे डाउनलोड नहीं करना।

मैं कुछ शोधों से गुज़रा और यह काम करने का दावा करता है लेकिन मुझे अपने कोड से कोई फ़र्क नहीं दिखता।

क्या मुझे अपने कोड में कुछ याद नहीं है?

मेरा सवाल पढ़ने के लिए धन्यवाद :)

जवाबों:


257

इसे मैंने अपने आवेदन के लिए हल किया है:

HTML: <a id="downloadAnchorElem" style="display:none"></a>

JS (शुद्ध JS, यहाँ jQuery नहीं):

var dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(storageObj));
var dlAnchorElem = document.getElementById('downloadAnchorElem');
dlAnchorElem.setAttribute("href",     dataStr     );
dlAnchorElem.setAttribute("download", "scene.json");
dlAnchorElem.click();

इस स्थिति में, storageObjवह जेएस ऑब्जेक्ट है जिसे आप स्टोर करना चाहते हैं, और "सीन.जसन" परिणामस्वरूप फ़ाइल के लिए केवल एक उदाहरण का नाम है।

इस दृष्टिकोण के अन्य प्रस्तावित लोगों पर निम्नलिखित लाभ हैं:

  • किसी भी HTML तत्व को क्लिक करने की आवश्यकता नहीं है
  • जैसा आप चाहते हैं वैसा ही नाम रिजल्ट होगा
  • कोई jQuery की जरूरत है

मुझे स्पष्ट क्लिक के बिना इस व्यवहार की आवश्यकता थी क्योंकि मैं js से कुछ बिंदु पर स्वचालित रूप से डाउनलोड को ट्रिगर करना चाहता हूं।

JS समाधान (HTML आवश्यक नहीं):

  function downloadObjectAsJson(exportObj, exportName){
    var dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(exportObj));
    var downloadAnchorNode = document.createElement('a');
    downloadAnchorNode.setAttribute("href",     dataStr);
    downloadAnchorNode.setAttribute("download", exportName + ".json");
    document.body.appendChild(downloadAnchorNode); // required for firefox
    downloadAnchorNode.click();
    downloadAnchorNode.remove();
  }

3
यह एकमात्र समाधान है जो डेटा के = ~ 2000 से अधिक वर्णों के लिए काम करेगा। क्योंकि आपने डेटा तैयार किया था:
rjurney

1
क्या कोई मुझे एक युक्ति या एमडीएन पृष्ठ की ओर संकेत कर सकता है जो अधिक विस्तार से बताता है कि यह पूरी तरह से डेटा प्रकार वाली चीज़ कैसे काम करती है। "डेटा: पाठ / json; charset = utf-8"? मैं इसका उपयोग कर रहा हूं, लेकिन यह जादू की तरह लगता है, विवरणों को पढ़ने के लिए बहुत अच्छा होगा, लेकिन मुझे यह भी नहीं पता कि इसके लिए Google कैसे होगा।
sidewinderguy

1
यह IE में काम नहीं करता है, हालांकि जब आपको 2000 से अधिक वर्णों के साथ एक बड़ी फ़ाइल डाउनलोड करनी होगी।
user388969

12
यह सीमा के बिना काम नहीं करेगा, यद्यपि। आप केवल 1MB डेटा डाउनलोड कर सकते हैं। उदाहरण के लिए, var storageObj = []; for (var i=0; i<1000000; ++i) storageObj.push('aaa');क्रोम 61 में “डाउनलोड फेल्ड - नेटवर्क एरर” देता है
oseiskar

1
JSON.stringify(exportObj, null, 2)इसके बजाय @YASHDAVE का उपयोग करें
TryingToImprove

40

एक उत्तर मिला।

var obj = {a: 123, b: "4 5 6"};
var data = "text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(obj));

$('<a href="data:' + data + '" download="data.json">download JSON</a>').appendTo('#container');

मेरे लिए ठीक काम करने लगता है।

** सारा श्रेय @ चरवाहे-बेन-अल्मन को जाता है, जो ऊपर दिए गए कोड के लेखक हैं **


@ क्या आप मुझे तीसरी पंक्ति समझा सकते हैं?
राहुल खत्री

आप डेटा को पहले से ही भेजना चाहेंगे: अपने url को, अन्यथा उपयोगकर्ता के कई ब्राउज़रों में 2000 वर्ण सीमा हिट होने की संभावना है।
21

अरे, मुझे पता है कि यह एक पुराना उत्तर है लेकिन,
जानिए

25

यह एक शुद्ध जेएस संस्करण होगा (चरवाहे से अनुकूलित):

var obj = {a: 123, b: "4 5 6"};
var data = "text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(obj));

var a = document.createElement('a');
a.href = 'data:' + data;
a.download = 'data.json';
a.innerHTML = 'download JSON';

var container = document.getElementById('container');
container.appendChild(a);

http://jsfiddle.net/sz76c083/1


3
2yrs होने के बाद भी प्रतिक्रिया के लिए धन्यवाद, क्योंकि मैंने यह प्रश्न पूछा था! मैं jQuery सिंटैक्स पर शुद्ध JS पसंद करता हूँ।
यूजीन यू

आप डेटा को पहले से ही भेजना चाहेंगे: अपने url को, अन्यथा उपयोगकर्ता के कई ब्राउज़रों में 2000 वर्ण सीमा हिट होने की संभावना है।
21

मैं इस डाउनलोड को पेज लोड पर कैसे शुरू कर सकता हूं। जब भी कोई उपयोगकर्ता पृष्ठ url ब्राउज़ करता है तो उसे डाउनलोड के लिए संकेत मिलता है
user388969

1
एज में आज का परीक्षण: data.json डाउनलोड नहीं किया जा सका।
सारा पेड़

25

आप प्रयोग करके देख सकते हैं:

  • देशी जावास्क्रिप्ट एपीआई की बूँद निर्माता और
  • FileSaver.js saveAs() विधि

किसी भी HTML तत्वों से निपटने की कोई आवश्यकता नहीं है।

var data = {
    key: 'value'
};
var fileName = 'myData.json';

// Create a blob of the data
var fileToSave = new Blob([JSON.stringify(data)], {
    type: 'application/json',
    name: fileName
});

// Save the file
saveAs(fileToSave, fileName);

यदि आप इस उत्तर के अनुसार JSON को प्रिंट करना चाहते हैं , तो आप इसका उपयोग कर सकते हैं:

JSON.stringify(data,undefined,2)

1
SaveAs () FileSaver.js से है - github.com/eligrey/FileSaver.js
गौतम

1
"किसी भी HTML तत्वों से निपटने की आवश्यकता नहीं है" ... और filesaver.js के स्रोत कोड को पढ़ना ... यह ठीक उसी तरह से करता है
वार

1
हाँ। मेरा कहने का मतलब था, सीधे HTML तत्वों से निपटने की कोई आवश्यकता नहीं है।
गौतम

3
यह सबसे अच्छा उत्तर है क्योंकि इसमें 1MB आकार की सीमा नहीं है और यह कस्टम हैक्स के बजाय एक पुस्तकालय का उपयोग करता है
oseiskar

FileSaver रेफरी के लिए मतदान किया। पूरी तरह से काम कर रहा है।
नॉन

15

निम्नलिखित ने मेरे लिए काम किया:

/* function to save JSON to file from browser
* adapted from http://bgrins.github.io/devtools-snippets/#console-save
* @param {Object} data -- json object to save
* @param {String} file -- file name to save to 
*/
function saveJSON(data, filename){

    if(!data) {
        console.error('No data')
        return;
    }

    if(!filename) filename = 'console.json'

    if(typeof data === "object"){
        data = JSON.stringify(data, undefined, 4)
    }

    var blob = new Blob([data], {type: 'text/json'}),
        e    = document.createEvent('MouseEvents'),
        a    = document.createElement('a')

    a.download = filename
    a.href = window.URL.createObjectURL(blob)
    a.dataset.downloadurl =  ['text/json', a.download, a.href].join(':')
    e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
    a.dispatchEvent(e)
}

और फिर इसे इस तरह से बुलाना

saveJSON(myJsonObject, "saved_data.json");

3
हालांकि यह एक महान जवाब है, initMouseEvent()एक है पदावनत वेब मानक और अब और नहीं किया जाना चाहिए। इसके बजाय, new MouseEvent()इंटरफ़ेस का उपयोग करें। हालांकि यह सिर्फ एक मामूली परावर्तक है।
मॉर्क्रो

10

मुझे हाल ही में एक बटन बनाना था जो एक बड़े फॉर्म के सभी मूल्यों की एक json फाइल डाउनलोड करेगा। आईई / एज / क्रोम के साथ काम करने के लिए मुझे इसकी आवश्यकता थी। यह जो मैंने किया है:

function download(text, name, type)
    {
        var file = new Blob([text], {type: type});
        var isIE = /*@cc_on!@*/false || !!document.documentMode;
        if (isIE)
        {
            window.navigator.msSaveOrOpenBlob(file, name);
        }
        else
        {
            var a = document.createElement('a');
            a.href = URL.createObjectURL(file);
            a.download = name;
            a.click();
        }
     }

download(jsonData, 'Form_Data_.json','application/json');

किनारे में फ़ाइल नाम और एक्सटेंशन के साथ एक मुद्दा था लेकिन लिखने के समय यह एज के साथ एक बग प्रतीत होता था जो तय होने के कारण होता है।

आशा है कि यह किसी की मदद करता है


यह क्रोम पर काम करता है, लेकिन फ़ायरफ़ॉक्स पर काम नहीं करता ... कृपया मदद करें! codepen.io/anon/pen/ePYPJb
उर्मिल पारिख

1
अच्छा काम, document.body.appendChild(a); a.style.display = 'none';फ़ायरफ़ॉक्स में इसे काम करने के लिए जोड़ें ।
फेबियन वॉन एलर्ट्स

5

उन लोगों के लिए सरल, स्वच्छ समाधान जो केवल आधुनिक ब्राउज़रों को लक्षित करते हैं:

function downloadTextFile(text, name) {
  const a = document.createElement('a');
  const type = name.split(".").pop();
  a.href = URL.createObjectURL( new Blob([text], { type:`text/${type === "txt" ? "plain" : type}` }) );
  a.download = name;
  a.click();
}

downloadTextFile(JSON.stringify(myObj), 'myObj.json');

धन्यवाद, केवल एक जिसने मुझे आकार के मुद्दे नहीं दिए
Roelant

4

downloadलिंक की संपत्ति नई है और इंटरनेट एक्सप्लोरर में समर्थित नहीं है ( यहां संगतता तालिका देखें )। इस समस्या के क्रॉस-ब्राउज़र समाधान के लिए मैं FileSaver.js पर एक नज़र डालूंगा


2

प्रतिक्रिया : इसे जोड़ें जहाँ आप अपने रेंडर विधि में चाहते हैं।

राज्य में वस्तु :

<a
  className="pull-right btn btn-primary"
  style={{ margin: 10 }}
  href={`data:text/json;charset=utf-8,${encodeURIComponent(
  JSON.stringify(this.state.objectToDownload)
  )}`}
  download="data.json"
>
  DOWNLOAD DATA AS JSON
</a>

सहारा में वस्तु :

<a
  className="pull-right btn btn-primary"
  style={{ margin: 10 }}
  href={`data:text/json;charset=utf-8,${encodeURIComponent(
  JSON.stringify(this.props.objectToDownload)
  )}`}
  download="data.json"
>
  DOWNLOAD DATA AS JSON
</a>

क्लासनेम और शैली वैकल्पिक हैं, अपनी आवश्यकताओं के अनुसार शैली को संशोधित करें।


1

अन्य MIME- प्रकार सेट करने का प्रयास करें: exportData = 'data:application/octet-stream;charset=utf-8,';

लेकिन सेव डायलॉग में फ़ाइल नाम के साथ समस्याएँ हो सकती हैं।


आपके देर से वापस आने के लिए क्षमा करें। मैंने आपके उत्तर की कोशिश की और यह फ़ाइल डाउनलोड करता है लेकिन इसमें गलत डेटा है .. :(
यूजीन यू

1
यह मेरे लिए काम करता है ... data = "data:application/octet-stream;charset=utf-8," + encodeURIComponent(JSON.stringify(data)); window.open(data); यह बस फ़ाइल को "डाउनलोड" के रूप में डाउनलोड करता है, लेकिन डेटा मैंने स्ट्रिंग किया और फिर यूरी-एन्कोड किया गया है जैसा कि यह होना चाहिए।
जेसन वीनर

0

यदि आप फ़ाइल नाम से कंसोल स्निपेट, रैसर पसंद करते हैं, तो आप ऐसा कर सकते हैं:

window.open(URL.createObjectURL(
    new Blob([JSON.stringify(JSON)], {
      type: 'application/binary'}
    )
))
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.