ব্লক হিসাবে চিত্রগুলি পুনরুদ্ধার করতে jQuery এর এজাক্স পদ্ধতি ব্যবহার করা


87

আমি সম্প্রতি আরেকটি (সম্পর্কিত) প্রশ্ন জিজ্ঞাসা করেছি, যা এই ফলোআপ প্রশ্নের দিকে নিয়ে যায়: ইনপুট ফর্মের জন্য কোনও ফাইলের পরিবর্তে ডেটা জমা দেওয়া

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) ব্রাউজারের ক্যাশে ব্যবহার করা। (২) প্রত্যাখ্যান করা হয়নি কারণ আমি চাই স্ক্রিপ্টটি কোনও চিত্র url কাজ করে। আমি কীভাবে ব্যবহার করব তা নিশ্চিত নই (1) বা (3) কারণ আমি একবার চিত্রটি ডাউনলোড করে নেওয়ার পরে আমার এটি একটি ব্লাবে রূপান্তর করতে হবে।
জাবলসাদ

বিকল্প 3 কেবলমাত্র যদি আপনি ইতিমধ্যে চিত্রটি ডাউনলোড করেন তবে কাজ করবে। প্রথমবারের জন্য আপনার আলাদা কিছু প্রয়োজন হবে। হতে পারে অপ্ট 1?
এরিক ফ্রিক

উত্তর:


151

আপনি jQuery আজাক্স দিয়ে এটি করতে পারবেন না, তবে দেশীয় এক্সএমএলএইচটিপিআরকোয়েস্ট দিয়ে।

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

বা

রেসপন্স টাইপ সেট করতে এক্সএইচআরফিল্ডস ব্যবহার করুন

    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এবং একটি formdata বস্তু এটিকে যুক্ত করুন ও Ajax মাধ্যমে এটি প্রেরণ করুন।
মুসা

4
+1, দুর্দান্ত কাজ করে! এবং এফওয়াইআই, অবশেষে খুব শীঘ্রই এটি jQuery এ যুক্ত হতে পারে: github.com/jquery/jquery/pull/1525
ল্যাম্বশান্সি

9
2017: jQuery এখনও 'ব্লব' টাইপ মোকাবেলা করতে সক্ষম নয়?
রোবসচ

4
'এক্সএইচআরফিল্ডস' jQuery 2 তেও কাজ করে (2.2.4 এ পরীক্ষিত)
Bampfer

17

আপনার যদি 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তবে নীচের বার্তাটি পাবেন:

মানটি কেবল তখনই অ্যাক্সেসযোগ্য যদি অবজেক্টটির 'প্রতিক্রিয়া টাইপ' '' বা 'পাঠ্য' (ছিল 'ব্লব')।


4
আপনাকে অনেক ধন্যবাদ! এটিই আমি সমাধান খুঁজছিলাম। পদ্ধতিতে "ব্লব" (আমার ক্ষেত্রে জিপ সংরক্ষণাগার) হিসাবে সফল প্রতিক্রিয়াটি হ্যান্ডেল করার জন্য আমার এজেএক্স দরকার ছিল .done()এবং যদি কিছু ভুল হয়ে যায় তবে .fail()পদ্ধতির প্রতিক্রিয়াটি "পাঠ্য" হিসাবে পরিচালনা করা উচিত, কারণ অন্যথায় এটি responseTextফাঁকা ছিল ইত্যাদি This সমাধান আমার জন্য নিখুঁতভাবে কাজ!
informatik01

4

@ মুসা আপনাকে একটি বড় ধন্যবাদ এবং এখানে একটি ঝরঝরে ফাংশন যা ডেটাটিকে একটি বেস 64 স্ট্রিংয়ে রূপান্তর করে। বাইনারি ফাইল পায় এমন একটি ওয়েবভিউতে বাইনারি ফাইল (পিডিএফ, পিএনজি, জেপিগ, ডকএক্স, ...) ফাইল পরিচালনা করার সময় এটি আপনার পক্ষে কার্যকর হতে পারে তবে আপনাকে ফাইলের ডেটা নিরাপদে আপনার অ্যাপে স্থানান্তর করতে হবে।

// 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);
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.