2012-01-08 29 views
15

सबसे पहले यहां पर एक ही शीर्षक के साथ question है, लेकिन यह वह नहीं है जिसे मैं ढूंढ रहा हूं और इसका पूरा उत्तर नहीं है।किसी उपयोगकर्तास्क्रिप्ट में XMLHttpRequest का उपयोग करके एक छवि डाउनलोड करना

तो मेरा प्रश्न यहां है। मान लें कि मेरे पास यह यूआरएल है जो एक छवि को निर्देशित करता है।

https://fbcdn-photos-a.akamaihd.net/hphotos-ak-ash4/299595_10150290138650735_543370734_8021370_355110168_n.jpg 

एक बार मैं URL के अंत में इस पैरामीटर ?dl=1 शब्दों में कहें, यह डाउनलोड करने योग्य हो जाता है।

https://fbcdn-photos-a.akamaihd.net/hphotos-ak-ash4/299595_10150290138650735_543370734_8021370_355110168_n.jpg?dl=1 

मैं इस कार्य को उपयोगकर्तास्क्रिप्ट के माध्यम से करने की कोशिश कर रहा हूं। तो मैंने इसके लिए XMLHttpRequest का उपयोग किया।

var url = "https://fbcdn-photos-a.akamaihd.net/hphotos-ak-ash4/299595_10150290138650735_543370734_8021370_355110168_n.jpg?dl=1"; 

var request = new XMLHttpRequest(); 
request.open("GET", url, false); 
request.send(null); 

if (request.status === 200) 
{ 
    alert(request.statusText); 
} 

यहां fiddle है।

लेकिन यह काम नहीं करता है। मेरे साथ सावधान रहें क्योंकि मैं जावास्क्रिप्ट के लिए काफी नया हूं और मैंने AJAX के साथ कुछ भी नहीं किया है। मैंने नमूने या कुछ भी के लिए बहुत कुछ किया लेकिन इसका कोई फायदा नहीं हुआ।

कृपया मुझे यह कैसे करना है इस पर मार्गदर्शन कर सकते हैं?

+0

'dl' तर्क अपने मामले में पूरी तरह से फर्जी – OnTheFly

+0

@ user539484 यू क्या मतलब है है:

स्क्रिप्ट कोड कुछ की तरह हो जाता है? यह वास्तव में कारगर है। बस पता बार पर कॉपी और पेस्ट करें। – Isuru

+0

मेरा मतलब है, इसका कारण प्रतिक्रिया शीर्षलेख देखें। यहां प्रासंगिक नहीं है। – OnTheFly

उत्तर

20

XMLHttpRequest क्रॉस-डोमेन काम नहीं करेगा, लेकिन जब से यह एक userscript क्रोम अब केवल userscripts में GM_xmlhttpRequest() का समर्थन करता है।

कुछ इस तरह काम करना चाहिए, ध्यान दें कि यह अतुल्यकालिक है:

GM_xmlhttpRequest ({ 
    method:   'GET', 
    url:   'https://fbcdn-photos-a.akamaihd.net/hphotos-ak-ash4/299595_10150290138650735_543370734_8021370_355110168_n.jpg?dl=1', 
    onload:   function (responseDetails) { 
         alert(responseDetails.statusText); 
        } 
}); 




हो रही है और वास्तविक छवि डेटा का उपयोग कर के रूप में, कि एक प्रमुख है काम करने के लिए दर्द।

  • आप Firefox लेकिन Chrome does not yet support it में नए .responseType = "blob"; कार्यक्षमता का उपयोग कर सकते हैं। (अभी तक)
    See it in action at jsBin.

    BlobBuilder    = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder; 
    
    var url     = "http://jsbin.com/images/gear.png"; 
    var request    = new XMLHttpRequest(); 
    request.open ("GET", url, false); 
    request.responseType = "arraybuffer"; 
    request.send (null); 
    
    if (request.status === 200) { 
        var bb    = new BlobBuilder(); 
        bb.append (request.response); // Note: not request.responseText 
    
        var blob   = bb.getBlob ('image/png'); 
        var reader   = new FileReader(); 
        reader.onload  = function (zFR_Event) { 
         $("body").prepend ('<p>New image: <img src="' + zFR_Event.target.result + '"></p>') 
        }; 
    
        reader.readAsDataURL (blob); 
    } 
    


  • दुर्भाग्य से, GM_xmlhttpRequest() नहीं करता है:

  • Chrome या Firefox एक ही डोमेन केवल के लिए में, आप तो जैसे नए XHR2 उपयोग कर सकते हैं समर्थन सेटिंग responseType



तो, जीएम स्क्रिप्ट या userscript अनुप्रयोगों के लिए, हम "Javascript Hacks: Using XHR to load binary data" में की तरह एक कस्टम बेस 64 एन्कोडिंग योजना का उपयोग करने के लिए है।

var imgUrl    = "http://jsbin.com/images/gear.png"; 

GM_xmlhttpRequest ({ 
    method:   'GET', 
    url:   imgUrl, 
    onload:   function (respDetails) { 
         var binResp  = customBase64Encode (respDetails.responseText); 

         /*-- Here, we just demo that we have a valid base64 encoding 
          by inserting the image into the page. 
          We could just as easily AJAX-off the data instead. 
         */ 
         var zImgPara = document.createElement ('p'); 
         var zTargetNode = document.querySelector ("body *"); //1st child 

         zImgPara.innerHTML = 'Image: <img src="data:image/png;base64,' 
              + binResp + '">'; 
         zTargetNode.parentNode.insertBefore (zImgPara, zTargetNode); 
        }, 
    overrideMimeType: 'text/plain; charset=x-user-defined' 
}); 


function customBase64Encode (inputStr) { 
    var 
     bbLen    = 3, 
     enCharLen   = 4, 
     inpLen    = inputStr.length, 
     inx     = 0, 
     jnx, 
     keyStr    = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" 
          + "/=", 
     output    = "", 
     paddingBytes  = 0; 
    var 
     bytebuffer   = new Array (bbLen), 
     encodedCharIndexes = new Array (enCharLen); 

    while (inx < inpLen) { 
     for (jnx = 0; jnx < bbLen; ++jnx) { 
      /*--- Throw away high-order byte, as documented at: 
       https://developer.mozilla.org/En/Using_XMLHttpRequest#Handling_binary_data 
      */ 
      if (inx < inpLen) 
       bytebuffer[jnx] = inputStr.charCodeAt (inx++) & 0xff; 
      else 
       bytebuffer[jnx] = 0; 
     } 

     /*--- Get each encoded character, 6 bits at a time. 
      index 0: first 6 bits 
      index 1: second 6 bits 
         (2 least significant bits from inputStr byte 1 
         + 4 most significant bits from byte 2) 
      index 2: third 6 bits 
         (4 least significant bits from inputStr byte 2 
         + 2 most significant bits from byte 3) 
      index 3: forth 6 bits (6 least significant bits from inputStr byte 3) 
     */ 
     encodedCharIndexes[0] = bytebuffer[0] >> 2; 
     encodedCharIndexes[1] = ((bytebuffer[0] & 0x3) << 4) | (bytebuffer[1] >> 4); 
     encodedCharIndexes[2] = ((bytebuffer[1] & 0x0f) << 2) | (bytebuffer[2] >> 6); 
     encodedCharIndexes[3] = bytebuffer[2] & 0x3f; 

     //--- Determine whether padding happened, and adjust accordingly. 
     paddingBytes   = inx - (inpLen - 1); 
     switch (paddingBytes) { 
      case 1: 
       // Set last character to padding char 
       encodedCharIndexes[3] = 64; 
       break; 
      case 2: 
       // Set last 2 characters to padding char 
       encodedCharIndexes[3] = 64; 
       encodedCharIndexes[2] = 64; 
       break; 
      default: 
       break; // No padding - proceed 
     } 

     /*--- Now grab each appropriate character out of our keystring, 
      based on our index array and append it to the output string. 
     */ 
     for (jnx = 0; jnx < enCharLen; ++jnx) 
      output += keyStr.charAt (encodedCharIndexes[jnx]); 
    } 
    return output; 
} 
+0

हाँ, यह काम करता है! धन्यवाद। :) छोटे सवाल, आप वास्तव में छवि को वास्तव में कैसे डाउनलोड कर सकते हैं? मैंने अन्य सभी तरीकों की कोशिश की लेकिन वे सभी वापस लौटते हैं, अनुरोध की स्थिति इत्यादि। – Isuru

+0

ठीक है .. मैंने ग्रीसस्पॉट पर 'ओवरराइड माइमटाइप 'तर्क के बारे में पढ़ा है लेकिन यह अधिक जानकारी प्रदान नहीं करता है। धन्यवाद :) – Isuru

+1

ठीक है, जवाब को अद्यतन किया गया है कि कैसे डेटा को पकड़ने और बेस 64 को एन्कोड करने के लिए दिखाया गया है (जो इसे पृष्ठ में उपयोग करने की अनुमति देता है या उपयोग करने योग्य रूप में सर्वर पर AJAXed बंद कर देता है)। –

3

आप एक अलग डोमेन पर एक्सएचआर का उपयोग कर संसाधन का अनुरोध करने का प्रयास कर रहे हैं और इस प्रकार अवरुद्ध है। एक्सएचआर का उपयोग कर क्रॉस-डोमेन मैसेजिंग के लिए सीओआरएस का उपयोग करें।

1

क्रॉफ ड्रैकुला सही है, आप किसी भिन्न डोमेन से कोई छवि लोड नहीं कर सकते हैं, लेकिन क्या आपको वास्तव में ऐसा करने की आवश्यकता है? आप img टैग बना और जोड़ सकते हैं और इसे लोड करने की प्रतीक्षा कर सकते हैं (jQuery load() जैसे कुछ के साथ)।

var img = document.createElement('img'); 
img.setAttribute('src', url); 
document.getElementsByTagName('body')[0].appendChild(img); 
+2

नहीं नहीं ... मैं छवि को किसी पृष्ठ पर एम्बेड नहीं करना चाहता हूं। मैं इसे एक्सएचआर का उपयोग करके डाउनलोड करना चाहता हूं। – Isuru

+1

मैं वास्तव में समझ नहीं पा रहा हूं कि आप क्या करने का प्रयास कर रहे हैं, लेकिन यदि आपको किसी पृष्ठ पर छवि का उपयोग करने की आवश्यकता है, तो आप इसे छुपा 'div' में जोड़ सकते हैं, उदाहरण के लिए, इसे कैश करने के लिए, और लोड करने के बाद जो कुछ भी आपको चाहिए यदि आपको केवल 'window.location =' http: //foo.com/bar? Dl = 1'' का उपयोग करके सहेजने वाला संवाद (ऊपर अपना लिंक देखें) दिखाने की आवश्यकता है। और यदि आपको वास्तव में सीओआरएस की तुलना में एक्सएचआर का उपयोग करने की ज़रूरत है तो शायद आपका एकमात्र विकल्प है। –