छवियों को एक बूँद के रूप में पुनः प्राप्त करने के लिए jQuery के अजाक्स विधि का उपयोग करना


84

मैंने हाल ही में एक और (संबंधित) प्रश्न पूछा है, जो इस प्रश्न का अनुसरण करता है: इनपुट फॉर्म के लिए फ़ाइल के बजाय डेटा सबमिट करना

JQuery.ajax () प्रलेखन ( http://api.jquery.com/jQuery.ajax/ ) के माध्यम से पढ़ना , ऐसा लगता है कि स्वीकृत डेटाटाइप की सूची में चित्र शामिल नहीं हैं।

मैं एक छवि को jQuery.get (या jQuery.ajax का उपयोग करता हूं, अगर मुझे करना है) को पुनः प्राप्त करने की कोशिश कर रहा हूं, तो इस छवि को एक ब्लॉब में संग्रहीत करें और इसे किसी अन्य सर्वर में पोस्ट अनुरोध में अपलोड करें। वर्तमान में, यह डेटाटाइप्स में बेमेल के कारण दिखता है, मेरी छवियां भ्रष्ट हो रही हैं (बाइट बेमेल में आकार, आदि)।

इसे निष्पादित करने के लिए कोड इस प्रकार है (यह कॉफ़ीस्क्रिप्ट में है, लेकिन पार्स करने के लिए मुश्किल नहीं होना चाहिए):

handler = (data,status) ->
  fd = new FormData
  fd.append("file", new Blob([data], { "type" : "image/png" }))
  jQuery.ajax {
    url: target_url,
    data: fd,
    processData: false,
    contentType: "multipart/form-data",
    type: "POST",
    complete: (xhr,status) ->
      console.log xhr.status
      console.log xhr.statusCode
      console.log xhr.responseText

  }
jQuery.get(image_source_url, null, handler)

मैं इस छवि को एक बूँद के रूप में कैसे पुनः प्राप्त कर सकता हूँ?


मुझे लगता है कि आपको सर्वर साइड में प्रतिक्रिया प्रकार बदलना होगा।
एरिक फ्रिक

मैं किसी भी यूआरएल से एक छवि को खींचने की कोशिश कर रहा हूं, न कि एक सर्वर जो मेरे पास जरूरी है।
जबलसाड


ऐसा लगता है कि उत्तर में तीन समाधान या तो (1) <img> टैग का उपयोग करते हैं, (2) सर्वर को बाइट्स 64 इनकोडेड के रूप में छवियों की सेवा करते हैं या (3) ब्राउज़र के कैश का उपयोग करते हैं। (2) को खारिज कर दिया गया है क्योंकि मैं चाहता हूं कि स्क्रिप्ट किसी भी छवि के लिए काम करे। मुझे यकीन नहीं है कि कैसे (1) या (3) का उपयोग करना है क्योंकि एक बार जब मैंने छवि डाउनलोड कर ली है तो मुझे इसे एक बूँद में बदलने की आवश्यकता है।
जुलासाद

विकल्प 3 केवल तभी काम करेगा जब आपने पहले ही छवि डाउनलोड कर ली हो। पहली बार आपको कुछ अलग करने की आवश्यकता होगी। शायद 1 का विकल्प चुन सकते हैं?
एरिक फ्रिक

जवाबों:


146

आप इसे jQuery के अजाक्स के साथ नहीं कर सकते, लेकिन मूल XMLHttpRequest के साथ कर सकते हैं।

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
    if (this.readyState == 4 && this.status == 200){
        //this.response is what you're looking for
        handler(this.response);
        console.log(this.response, typeof this.response);
        var img = document.getElementById('img');
        var url = window.URL || window.webkitURL;
        img.src = url.createObjectURL(this.response);
    }
}
xhr.open('GET', 'http://jsfiddle.net/img/logo.png');
xhr.responseType = 'blob';
xhr.send();      

संपादित करें

इसलिए इस विषय पर फिर से विचार करना, ऐसा लगता है कि jQuery 3 के साथ ऐसा करना वास्तव में संभव है

jQuery.ajax({
        url:'https://images.unsplash.com/photo-1465101108990-e5eac17cf76d?ixlib=rb-0.3.5&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ%3D%3D&s=471ae675a6140db97fea32b55781479e',
        cache:false,
        xhr:function(){// Seems like the only way to get access to the xhr object
            var xhr = new XMLHttpRequest();
            xhr.responseType= 'blob'
            return xhr;
        },
        success: function(data){
            var img = document.getElementById('img');
            var url = window.URL || window.webkitURL;
            img.src = url.createObjectURL(data);
        },
        error:function(){
            
        }
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
<img id="img" width=100%>

या

प्रतिक्रिया टाइप सेट करने के लिए xhrFields का उपयोग करें

    jQuery.ajax({
            url:'https://images.unsplash.com/photo-1465101108990-e5eac17cf76d?ixlib=rb-0.3.5&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ%3D%3D&s=471ae675a6140db97fea32b55781479e',
            cache:false,
            xhrFields:{
                responseType: 'blob'
            },
            success: function(data){
                var img = document.getElementById('img');
                var url = window.URL || window.webkitURL;
                img.src = url.createObjectURL(data);
            },
            error:function(){
                
            }
        });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
    <img id="img" width=100%>


धन्यवाद। मैंने अभी इसका पता लगाया और आपका उत्तर देखा। यह मेरे समान है (इस तथ्य के अलावा कि मैं इसे एक <img> ऑब्जेक्ट पर सेट करने के बजाय एक फॉर्म में पोस्ट करता हूं)। मैं इसे वैसे भी सही के रूप में चिह्नित कर
लूंगा

@jabalsad ने पूछा How can I retrieve this image as a blob instead?, वैसे भी यह सिर्फ इसे प्रदर्शित करने के लिए था, इसे एक फॉर्मडैट ऑब्जेक्ट में handlerले जाएगा this.responseऔर इसे अजाक्स के माध्यम से भेज देगा।
मूसा

2
+1, बढ़िया काम करता है! और FYI करें, यह अंत में जल्द ही jQuery में जुड़ सकता है: github.com/jquery/jquery/pull/1525
lambshaanxy

9
2017: jQuery अभी भी 'बूँद' प्रकार से निपटने में सक्षम नहीं है?
रोज़बेक

1
'xhrFields' jQuery 2 (2.2.4 में परीक्षण किया गया) में भी काम करती है
बैम्फर

15

यदि आपको jQuery.AJAX का उपयोग करके त्रुटि संदेशों को संभालने की आवश्यकता है, तो आपको फ़ंक्शन को संशोधित करने की आवश्यकता होगी ताकि त्रुटि होने पर इसे संशोधित नहीं किया जा सके।xhrresponseType

तो आपको responseType" बूँद " को संशोधित करना होगा, यदि यह एक सफल कॉल है:

$.ajax({
    ...
    xhr: function() {
        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function() {
            if (xhr.readyState == 2) {
                if (xhr.status == 200) {
                    xhr.responseType = "blob";
                } else {
                    xhr.responseType = "text";
                }
            }
        };
        return xhr;
    },
    ...
    error: function(xhr, textStatus, errorThrown) {
        // Here you are able now to access to the property "responseText"
        // as you have the type set to "text" instead of "blob".
        console.error(xhr.responseText);
    },
    success: function(data) {
        console.log(data); // Here is "blob" type
    }
});

ध्यान दें

यदि आप डीबग करते हैं और xhr.responseType" बूँद " सेट करने के बाद बिंदु पर ब्रेकपॉइंट लगाते हैं, तो आप ध्यान दे सकते हैं कि यदि आप इसके लिए मान प्राप्त करने का प्रयास करते हैं, तो आपको responseTextनिम्न संदेश मिलेगा:

मान केवल तभी सुलभ होता है जब ऑब्जेक्ट का 'रिस्पांस टाइप' '' या 'टेक्स्ट' ('ब्लॉब' होता है)।


1
आपका बहुत बहुत धन्यवाद! यह वह उपाय था जिसकी मुझे तलाश थी। मुझे .done()विधि में "बूँद" (मेरे मामले में ज़िप संग्रह) के रूप में सफल प्रतिक्रिया को संभालने के लिए AJAX की आवश्यकता थी , और अगर कुछ गलत हुआ, तो .fail()विधि में प्रतिक्रिया को "पाठ" के रूप में संभाला जाना चाहिए, क्योंकि अन्यथा responseTextखाली था आदि। समाधान पूरी तरह से मेरे लिए काम किया!
informatik01

4

@Musa के लिए एक बड़ा धन्यवाद और यहां एक साफ फ़ंक्शन है जो डेटा को बेस 64 स्ट्रिंग में परिवर्तित करता है। बाइनरी फ़ाइल (बाइनरी फ़ाइल) प्राप्त करने वाले WebView में एक बाइनरी फ़ाइल (PDF, png, jpeg, docx, ...) फ़ाइल को हैंडल करते समय यह आपके काम आ सकता है लेकिन आपको फ़ाइल के डेटा को सुरक्षित रूप से अपने ऐप में स्थानांतरित करने की आवश्यकता है।

// runs a get/post on url with post variables, where:
// url ... your url
// post ... {'key1':'value1', 'key2':'value2', ...}
//          set to null if you need a GET instead of POST req
// done ... function(t) called when request returns
function getFile(url, post, done)
{
   var postEnc, method;
   if (post == null)
   {
      postEnc = '';
      method = 'GET';
   }
   else
   {
      method = 'POST';
      postEnc = new FormData();
      for(var i in post)
         postEnc.append(i, post[i]);
   }
   var xhr = new XMLHttpRequest();
   xhr.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200)
      {
         var res = this.response;
         var reader = new window.FileReader();
         reader.readAsDataURL(res); 
         reader.onloadend = function() { done(reader.result.split('base64,')[1]); }
      }
   }
   xhr.open(method, url);
   xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
   xhr.send('fname=Henry&lname=Ford');
   xhr.responseType = 'blob';
   xhr.send(postEnc);
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.