在用户脚本中使用XMLHttpRequest下载图像 [英] Downloading an image using XMLHttpRequest in a userscript
问题描述
所以这是我的问题。说我有这个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 settingresponseType
.
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屋!