ऑब्जेक्ट URL से फ़ाइल या ब्लॉब कैसे प्राप्त करें?


127

मैं उपयोगकर्ता को ड्रैग एंड ड्रॉप और अन्य तरीकों के माध्यम से पेज में छवियों को लोड करने की अनुमति दे रहा हूं। जब एक छवि को गिरा दिया जाता है, तो मैं URL.createObjectURLछवि को प्रदर्शित करने के लिए ऑब्जेक्ट URL में परिवर्तित करने के लिए उपयोग कर रहा हूं । मैं url को रद्द नहीं कर रहा हूं, क्योंकि मैं इसका पुन: उपयोग करता हूं।

इसलिए, जब किसी FormDataवस्तु को बनाने का समय आता है, तो मैं उन्हें उन चित्रों में से एक के साथ एक फॉर्म अपलोड करने की अनुमति दे सकता हूं, क्या ऐसा कोई तरीका है जिससे मैं उस ऑब्जेक्ट URL को वापस एक में उलट सकता हूं Blobया Fileइसलिए मैं इसे एक में जोड़ सकता हूं। FormDataवस्तु?


पिछले दो टिप्पणियों के बारे में कुछ भी नहीं - आपको बस इतना करना चाहिए कि एक XMLHttpRequestको भेजे गए URL पर भेज दें ।
गेंग्केव

2
केवल मूल फ़ाइल ऑब्जेक्ट्स को कहीं स्टोर क्यों नहीं किया जाता है, फिर उन्हें प्रदर्शित करने के लिए ऑब्जेक्ट URL का उपयोग करें और मूल फ़ाइलों का उपयोग करने के लिए फॉर्म सबमिट करें?
user764754

@ user764754 क्योंकि उपयोगकर्ता द्वारा अपलोड की जा रही फ़ाइल का URL "C: \ fakepath" के रूप में प्राप्त करने की कोशिश कर रहा है
मैल्कम सल्वाडोर

जवाबों:


88

आधुनिक समाधान:

let blob = await fetch(url).then(r => r.blob());

Url एक ऑब्जेक्ट url या एक सामान्य url हो सकता है।


3
अच्छा लगा। ES5 की चीजों को इस तरह सरल बनाने में खुशी होगी।
ब्रायनफ्रेंड

11
और अगर आप सीधे वादे से एक फ़ाइल प्राप्त करना चाहते हैं, तो आप निम्नानुसार एक फ़ाइल उत्पन्न कर सकते हैं। let file = await fetch(url).then(r => r.blob()).then(blobFile => new File([blobFile], "fileNameGoesHere", { type: "image/png" })
dbakiu

3
दुर्भाग्य से, यह समाधान मेरे लिए क्रोम में काम नहीं करता है। ब्राउज़र इस URL को लोड करने में विफल रहता है।
वाल्डजिस्ट

Waldgeist, क्या आपने इसे createObjectUrl () में लपेटा था?
मैट फ्लेचर

73

जैसा कि गेंगकेव ने अपनी टिप्पणी में कहा है, यह ऐसा करने के लिए सबसे अच्छा / एकमात्र तरीका है जैसा कि एक async xhr2 कॉल के साथ है:

var xhr = new XMLHttpRequest();
xhr.open('GET', 'blob:http%3A//your.blob.url.here', true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
  if (this.status == 200) {
    var myBlob = this.response;
    // myBlob is now the blob that the object URL pointed to.
  }
};
xhr.send();

अद्यतन (2018): उन स्थितियों के लिए जहां ईएस 5 सुरक्षित रूप से उपयोग किया जा सकता है, जो नीचे एक सरल ईएस 5-आधारित उत्तर है।


19
आपके पास कभी कोई ऑब्जेर्एल होगा जो वर्तमान डोमेन और स्कोप के लिए स्थानीय नहीं है?
ब्रायनफ्रायड

4
मैंने इसे ऊपर की तरह ही किया, लेकिन 404 नहीं मिला। क्या चल रहा है?
अल्बर्ट यू

कृपया ध्यान दें कि कुछ ब्राउज़र (पुराना IE पढ़ें ...), अगर आपको उन पोस्ट को देखने की जरूरत है, तो stackoverflow.com/questions/17657184/…
mraxus

4
@BrianFreud "जब आप कभी भी एक ऑब्जेक्टूरल करेंगे जो वर्तमान डोमेन और स्कोप के लिए स्थानीय नहीं है?" मेरे मामले में मैं एक अमेज़ॅन एस 3 बूँद को एक अलग फ़ाइल नाम देने की कोशिश कर रहा हूं, जो वर्तमान में एस 3 पर एक "गाइड" है जो विस्तार के बिना है। इसलिए, मेरे मामले में मैं एक क्रॉस-डोमेन कॉल का उपयोग कर रहा हूं।
वैगनर बर्तोलिनी जूनियर

6
"ऑब्जेक्ट URL ऐसे URL हैं जो डिस्क पर फ़ाइलों की ओर इशारा करते हैं।" परिभाषा के अनुसार ऑब्जेक्ट केवल स्थानीय हो सकते हैं।
ब्रायनफ्रेंड

12

रिएक्ट / नोड / एक्सियोस के साथ काम करते समय शायद किसी को यह उपयोगी लगता है। मैंने react-dropzoneयूआई पर अपनी क्लाउडिनरी इमेज अपलोड सुविधा के लिए इसका उपयोग किया ।

    axios({
        method: 'get',
        url: file[0].preview, // blob url eg. blob:http://127.0.0.1:8000/e89c5d87-a634-4540-974c-30dc476825cc
        responseType: 'blob'
    }).then(function(response){
         var reader = new FileReader();
         reader.readAsDataURL(response.data); 
         reader.onloadend = function() {
             var base64data = reader.result;
             self.props.onMainImageDrop(base64data)
         }

    })

1
क्या यह क्रॉस डोमेन अनुरोधों के लिए काम करता है? ट्विटर के वीडियो में ब्लॉब URL है। मुझे उस बूँद ऑब्जेक्ट को इकट्ठा करने में सक्षम होना चाहिए जो बूँद URL इंगित कर रहा है। मैं ब्राउज़र में fetch api का उपयोग कर रहा हूं, जो मुझे यह त्रुटि दे रहा है - Refused to connect to 'blob:https://twitter.com/9e00aec3-6729-42fb-b5a7-01f50be302fa' because it violates the following Content Security Policy directive: "connect-src । क्या आप एक संकेत दे सकते हैं कि मैं क्या गलत कर सकता हूं / नहीं मिल रहा है?
गादाद्रिवर

मैं इस वन-लाइनर का उपयोग डेटा प्रॉपर्टी के रूप में बूँद के साथ परिणाम प्राप्त करने में सक्षम था: कॉन्स्ट परिणाम = प्रतीक्षा axios.get (url, {responseType: "blob"});
नूह स्टाल


4

नीचे दिए गए उदाहरण के लिए भ्रूण का उपयोग करना:

 fetch(<"yoururl">, {
    method: 'GET',
    headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + <your access token if need>
    },
       })
.then((response) => response.blob())
.then((blob) => {
// 2. Create blob link to download
 const url = window.URL.createObjectURL(new Blob([blob]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', `sample.xlsx`);
 // 3. Append to html page
 document.body.appendChild(link);
 // 4. Force download
 link.click();
 // 5. Clean up and remove the link
 link.parentNode.removeChild(link);
})

आप परीक्षण करने के लिए क्रोम कंसोल पर पेस्ट कर सकते हैं। फ़ाइल को 'sample.xlsx' के साथ डाउनलोड करने की आशा है कि यह मदद कर सकता है!


मुझे लगता है कि ओपी ने एक बूँद यूआरएल को वास्तविक फ़ाइल / ब्लॉब में बदलने के बारे में पूछा, बजाय अन्य तरीके के।
अभिषेक घोष

3

दुर्भाग्य से @ BrianFreud का उत्तर मेरी आवश्यकताओं के अनुरूप नहीं है, मुझे थोड़ी अलग आवश्यकता थी, और मुझे पता है कि @ BrianFreud के प्रश्न का उत्तर नहीं है, लेकिन मैं इसे यहाँ छोड़ रहा हूँ क्योंकि बहुत सारे लोग मेरी इसी आवश्यकता के साथ यहाँ आए थे। मुझे कुछ इस तरह की आवश्यकता थी कि 'फाइल कैसे प्राप्त करें या URL से ब्लॉब करें?', और वर्तमान सही उत्तर मेरी ज़रूरतों को पूरा नहीं करता है क्योंकि इसका क्रॉस-डोमेन नहीं है।

मेरे पास एक वेबसाइट है जो अमेज़ॅन एस 3 / एज़्योर स्टोरेज से छवियों का उपभोग करती है, और वहां मैं अद्वितीय पहचानकर्ताओं के साथ नामित वस्तुओं को संग्रहीत करता हूं:

नमूना: http: //****.blob.core.windows.net/systemimages/bf142dc9-0185-4aee-a3f4-1e5e95a09bcf

इस चित्र में से कुछ को हमारे सिस्टम इंटरफ़ेस से डाउनलोड किया जाना चाहिए। मेरे HTTP सर्वर के माध्यम से इस ट्रैफ़िक को पारित करने से बचने के लिए, क्योंकि इस ऑब्जेक्ट को एक्सेस करने के लिए किसी भी सुरक्षा की आवश्यकता नहीं है (डोमेन फ़िल्टरिंग को छोड़कर), मैंने उपयोगकर्ता के ब्राउज़र पर एक सीधा अनुरोध करने और फ़ाइल को वास्तविक नाम देने के लिए स्थानीय प्रसंस्करण का उपयोग करने का निर्णय लिया विस्तार।

यह पूरा करने के लिए कि मैंने हेनरी एल्गस के इस बेहतरीन लेख का उपयोग किया है: http://www.henryalgus.com/reading-binary-files-use-jquery-ajax/

1. पहला कदम: jquery में द्विआधारी समर्थन जोड़ें

/**
*
* jquery.binarytransport.js
*
* @description. jQuery ajax transport for making binary data type requests.
* @version 1.0 
* @author Henry Algus <henryalgus@gmail.com>
*
*/

// use this transport for "binary" data type
$.ajaxTransport("+binary", function (options, originalOptions, jqXHR) {
    // check for conditions and support for blob / arraybuffer response type
    if (window.FormData && ((options.dataType && (options.dataType == 'binary')) || (options.data && ((window.ArrayBuffer && options.data instanceof ArrayBuffer) || (window.Blob && options.data instanceof Blob))))) {
        return {
            // create new XMLHttpRequest
            send: function (headers, callback) {
                // setup all variables
                var xhr = new XMLHttpRequest(),
        url = options.url,
        type = options.type,
        async = options.async || true,
        // blob or arraybuffer. Default is blob
        dataType = options.responseType || "blob",
        data = options.data || null,
        username = options.username || null,
        password = options.password || null;

                xhr.addEventListener('load', function () {
                    var data = {};
                    data[options.dataType] = xhr.response;
                    // make callback and send data
                    callback(xhr.status, xhr.statusText, data, xhr.getAllResponseHeaders());
                });

                xhr.open(type, url, async, username, password);

                // setup custom headers
                for (var i in headers) {
                    xhr.setRequestHeader(i, headers[i]);
                }

                xhr.responseType = dataType;
                xhr.send(data);
            },
            abort: function () {
                jqXHR.abort();
            }
        };
    }
});

2. दूसरा चरण: इस परिवहन प्रकार का उपयोग करके अनुरोध करें।

function downloadArt(url)
{
    $.ajax(url, {
        dataType: "binary",
        processData: false
    }).done(function (data) {
        // just my logic to name/create files
        var filename = url.substr(url.lastIndexOf('/') + 1) + '.png';
        var blob = new Blob([data], { type: 'image/png' });

        saveAs(blob, filename);
    });
}

अब आप जिस ब्लूब को बनाया है उसका उपयोग कर सकते हैं, मेरे मामले में मैं इसे डिस्क पर सहेजना चाहता हूं।

3. वैकल्पिक: FileSaver का उपयोग करके उपयोगकर्ता के कंप्यूटर पर फ़ाइल सहेजें

मैंने डाउनलोड की गई फ़ाइल को डिस्क में सहेजने के लिए FileSaver.js का उपयोग किया है, अगर आपको इसे पूरा करने की आवश्यकता है, तो कृपया इस जावास्क्रिप्ट लाइब्रेरी का उपयोग करें:

https://github.com/eligrey/FileSaver.js/

मैं यह अपेक्षा करता हूं कि और अधिक विशिष्ट आवश्यकताओं के साथ दूसरों की मदद करें।


1
ObjecturLs स्थानीय रूप से हैं। ऑब्जेक्ट URL वे URL होते हैं जो डिस्क पर फ़ाइलों की ओर इशारा करते हैं। यह देखते हुए कि क्रॉस-डोमेन ऑब्जेक्टुरल जैसी कोई चीज नहीं है, आप दो अलग-अलग अवधारणाओं का मुकाबला कर रहे हैं, इस प्रकार दिए गए समाधान का उपयोग करके आपकी समस्या।
ब्रायनफ्रेंड

1
@BrianFreud मुझे ऐसा मिला जो इस प्रश्न का उत्तर नहीं है। लेकिन मुझे अभी भी लगता है कि इसका एक अच्छा उत्तर छोड़ने के लिए जब से मैं यहां आया था एक छोटे से अलग प्रश्न का उत्तर ढूंढ रहा था कि 'फाइल कैसे प्राप्त करें या URL से ब्लॉब करें?'। यदि आप स्वयं उत्तर की जांच करते हैं, तो '10 पर क्रॉस डोमेन अनुरोधों के मामले में यह काम नहीं करता है।' '। तो 10 से अधिक व्यक्तियों को यहाँ की तलाश में मिला। मैंने तय किया कि फिर इसे यहीं छोड़ दूंगा।
वैगनर बर्तोलिनी जूनियर

समस्या यह है कि, आपका उत्तर जानबूझकर इस प्रश्न का उत्तर नहीं देता है। एक सामान्य URL और ऑब्जेक्ट URL दो पूरी तरह से अलग चीजें हैं। के बारे में # upvotes पर "यह क्रॉस डोमेन अनुरोधों के मामले में काम नहीं करता है।" सामान्य URL और ऑब्जेक्ट URL को भ्रमित करके यहां चीजों को भ्रमित करने से?
ब्रायनफ्रायड

@BrianFreud मेरे जवाब पर एक संपादन का सुझाव देने के लिए स्वतंत्र महसूस करता है। मैं इस विषय के बारे में अध्ययन करूंगा, शायद मुझे गलत समझ में आया कि एक "ऑब्जेक्ट यूआरएल" बनाम "ऑब्जेक्ट यूआरएल" है ... अंग्रेजी मेरा मूल नहीं है। मैं बेहतर उत्तर देने के लिए विषय के बारे में एक शोध करूंगा। लेकिन मुझे लगता है कि अन्य लोग हैं जो यहां कुछ अलग करने की तलाश में आते हैं। मैंने यहाँ पहुँचने के लिए "objectURL" की खोज नहीं की, यह मेरी बात पहले थी। लेकिन मैं तुम्हें भी मिल गया।
वैगनर बर्तोलिनी जूनियर

2

यदि आप फ़ाइल को किसी कैनवास में दिखाते हैं, तो आप कैनवास सामग्री को एक बूँद ऑब्जेक्ट में भी बदल सकते हैं।

canvas.toBlob(function(my_file){
  //.toBlob is only implemented in > FF18 but there is a polyfill 
  //for other browsers https://github.com/blueimp/JavaScript-Canvas-to-Blob
  var myBlob = (my_file);
})

2
ध्यान दें कि वास्तव में आपको वही मूल फ़ाइल वापस नहीं दी जा रही है ; यह मक्खी पर एक नई छवि फ़ाइल बना रहा है। जब मैंने आखिरी बार परीक्षण किया था कि कुछ साल पहले, मैंने पाया कि कम से कम क्रोम में, नई छवि फ़ाइल बिल्कुल संकुचित नहीं है - मैंने 10k jpgs को 2.5 mb jpgs में बदल दिया था।
ब्रायनफ्रेंड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.