2012-08-09 15 views
76

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

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

+0

पिछले दो टिप्पणियों के बारे में कभी भी नहीं - आपको केवल ब्लॉब यूआरएल में 'XMLHttpRequest' भेजना है। – gengkev

+7

क्या एक शानदार सवाल है! –

+0

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

उत्तर

52

gengkev ऊपर अपने टिप्पणी में की तरफ इशारा करता है, यह सबसे अच्छा/केवल इस एक 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(); 
+14

यह क्रॉस डोमेन अनुरोधों के मामले में काम नहीं करता है। –

+14

आपके पास कभी * a objectURL * होगा जो वर्तमान डोमेन और दायरे के लिए स्थानीय नहीं है? – BrianFreud

+4

मैंने इसे ऊपर जैसा ही किया, लेकिन xhr के साथ 404 नहीं मिला। क्या चल रहा है? –

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); 
}) 
+1

ध्यान दें कि यह वास्तव में आपको * समान * मूल फ़ाइल वापस नहीं दे रहा है; यह फ्लाई पर एक नई छवि फ़ाइल बना रहा है। जब मैंने पिछले कुछ साल पहले परीक्षण किया था, मैंने पाया कि कम से कम क्रोम में, नई छवि फ़ाइल बिल्कुल संपीड़ित नहीं है - मेरे पास 2.5 एमबी जेपीजी में 10k जेपीजी बदल रहा था। – BrianFreud

3

जो बताते हैं कि BlobBuilder क्रोम में काम नहीं करता है तो आप उपयोग करने की आवश्यकता Getting BLOB data from XHR request देखें:

xhr.responseType = 'arraybuffer'; 
0

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

मैं एक वेबसाइट है कि एक अमेज़न S3/Azure संग्रहण से छवियों की खपत है, और मैं uniqueidentifiers साथ नामित वस्तुओं की दुकान:

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

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

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

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

/** 
* 
* jquery.binarytransport.js 
* 
* @description. jQuery ajax transport for making binary data type requests. 
* @version 1.0 
* @author Henry Algus <[email protected]> 
* 
*/ 

// 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

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

+1

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

+0

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

1

शायद किसी को प्रतिक्रिया/नोड/एक्सिस के साथ काम करते समय यह उपयोगी लगता है। मैंने यूआई पर 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) 
     } 

    }) 
संबंधित मुद्दे