在用户脚本中使用XMLHttpRequest下载图像 [英] Downloading an image using XMLHttpRequest in a userscript

查看:132
本文介绍了在用户脚本中使用XMLHttpRequest下载图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,有一个问题在这里与SO相同,但不是我正在寻找而且没有完整的答案。



所以这是我的问题。说我有这个URL指向一个图像。

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

一旦我把这个参数?dl = 1 到URL的末尾,它可以下载。

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

这是一个小提琴



但它不起作用。对我来说,我对JavaScript很新,我也没有对AJAX做任何事情。我已经对样品或任何东西进行了很多搜索,但无效。



请问有谁能指导我如何做到这一点?

解决方案

XMLHttpRequest 将不会跨域运作,一个 userscript Chrome现在只支持 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中使用新的 .responseType =blob; 功能,一个href =http://code.google.com/p/chromium/issues/detail?id=52486> Chrome不支持它。


  • 在Chrome或Firefox中,仅适用于同一个域,您可以使用新的 XHR2 ,如下所示:

    请参阅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); //注意:not request.responseText

    var blob = bb.getBlob('image / png');
    var reader = new FileReader();
    reader.onload = function(zFR_Event){
    $(body)。prepend('< p>新图像:< img src ='+ zFR_Event.target.result +' >< / p>')
    };

    reader.readAsDataURL(blob);
    }



  • 不幸的是, GM_xmlhttpRequest()不支持设置 responseType








所以,对于GM脚本或用户脚本应用程序,我们必须使用自定义base64编码例如Javascript Hacks:使用XHR加载二进制数据



脚本代码变成如下:

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

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

/ * - 这里,我们只是演示,我们有一个有效的base64编码
通过插入图像到页面
我们可以很容易的AJAX
* /
var zImgPara = document.createElement('p');
var zTargetNode = document.querySelector(body *); //第一个孩子

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


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

while(inx< inpLen){
for(jnx = 0; jnx< bbLen; ++ jnx){
/ * ---抛出高阶字节,如以下文档所示:
https://developer.mozilla.org/En/Using_XMLHttpRequest#Handling_binary_data
* /
if(inx< inpLen)
bytebuffer [jnx] = inputStr.charCodeAt(inx ++)& 0xFF的;
else
bytebuffer [jnx] = 0;
}

/ * ---获取每个编码字符,一次6位。
索引0:前6位
索引1:第6位
(2个来自inputStr字节的最低有效位1
+ 4个来自字节2的最高有效位)
索引2:第三个6位
(4个来自inputStr字节的最低有效位2
+ 2个来自字节3的最高有效位)
索引3:前6位(来自inputStr字节的6个最低有效位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的;

// ---确定填充是否发生,并相应调整。
paddingBytes = inx - (inpLen - 1);
switch(paddingBytes){
case 1:
//将最后一个字符设置为padding char
encodedCharIndexes [3] = 64;
break;
case 2:
//将最后2个字符设置为填充char
encodedCharIndexes [3] = 64;
encodedCharIndexes [2] = 64;
break;
默认值:
break; //没有填充 - 继续
}

/ * ---现在从我们的keystring中获取每个适当的字符,
基于我们的索引数组,并将其附加到输出字符串。
* /
for(jnx = 0; jnx< enCharLen; ++ jnx)
输出+ = keyStr.charAt(encodedCharIndexes [jnx]);
}
返回输出;
}


First of all there is a question with the same title here on SO but its not what I'm looking for and it doesn't have a complete answer either.

So here's my question. Say I have this URL which directs to an image.

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

Once I put this parameter ?dl=1 to the end of the URL, it becomes downloadable.

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

I'm trying to do this task through a userscript. So I used XMLHttpRequest for that.

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

Here is a fiddle.

But it does not work. Bare with me for I'm quite new to JavaScript and I haven't done anything with AJAX either. I googled a lot for samples or anything but to no avail.

Please can anyone guide me on how to do this?

解决方案

XMLHttpRequest will not work cross-domain, but since this is a userscript Chrome now supports GM_xmlhttpRequest() in userscripts only.

Something like this should work, note that it is asynchronous:

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




As for getting and using the actual image data, that is a major pain to work out.

  • You can use the new .responseType = "blob"; functionality in Firefox but Chrome does not yet support it.

  • In Chrome or Firefox, for the same domain only, you can use the new XHR2 like so:
    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);
    }
    


  • Unfortunately, GM_xmlhttpRequest() does not (yet) support setting responseType.


So, for GM script or userscript applications, we have to use a custom base64 encoding scheme like in "Javascript Hacks: Using XHR to load binary data".

The script code becomes something like:

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"
                            + "0123456789+/=",
        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;
}

这篇关于在用户脚本中使用XMLHttpRequest下载图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆