我允许用户通过拖放和其他方法将图像加载到页面中。当图像被删除时,我使用URL。createObjectURL转换为显示图像的对象URL。我没有撤销url,因为我重用了它。
因此,当需要创建一个FormData对象时我可以允许他们上传一个包含这些图像的表单,有什么方法可以将对象URL反向到Blob或File中,这样我就可以将它附加到FormData对象中?
我允许用户通过拖放和其他方法将图像加载到页面中。当图像被删除时,我使用URL。createObjectURL转换为显示图像的对象URL。我没有撤销url,因为我重用了它。
因此,当需要创建一个FormData对象时我可以允许他们上传一个包含这些图像的表单,有什么方法可以将对象URL反向到Blob或File中,这样我就可以将它附加到FormData对象中?
当前回答
现代的解决方案:
let blob = await fetch(url).then(r => r.blob());
url可以是对象url,也可以是普通url。
其他回答
不幸的是,@布莱恩·弗洛伊德的答案不符合我的需求,我有一点不同的需求,我知道这不是@布莱恩·弗洛伊德问题的答案,但我把它留在这里,因为很多人都带着我同样的需求来到这里。我需要一些类似“如何从URL获取文件或blob ?”,当前的正确答案不符合我的需要,因为它不是跨域的。
我有一个网站,从Amazon S3/Azure存储中消费图像,在那里我存储了以uniqueidentifier命名的对象:
示例:http:// * * * * .blob.core.windows.net/systemimages/bf142dc9 - 0185 - 4 -爱意e5e95a09bcf——a3f4 - 1
其中一些映像应该从我们的系统界面下载。 为了避免通过我的HTTP服务器传递此流量,因为该对象不需要访问任何安全性(通过域过滤除外),我决定在用户浏览器上直接发出请求,并使用本地处理为文件提供真实名称和扩展名。
为了达到这个目的,我引用了Henry Algus的这篇很棒的文章: http://www.henryalgus.com/reading-binary-files-using-jquery-ajax/
1. 第一步:为jquery添加二进制支持
/**
*
* jquery.binarytransport.js
*
* @description. jQuery ajax transport for making binary data type requests.
* @version 1.0
* @author Henry Algus <henryalgus@gmail.com>
*
*/
// use this transport for "binary" data type
$.ajaxTransport("+binary", function (options, originalOptions, jqXHR) {
// check for conditions and support for blob / arraybuffer response type
if (window.FormData && ((options.dataType && (options.dataType == 'binary')) || (options.data && ((window.ArrayBuffer && options.data instanceof ArrayBuffer) || (window.Blob && options.data instanceof Blob))))) {
return {
// create new XMLHttpRequest
send: function (headers, callback) {
// setup all variables
var xhr = new XMLHttpRequest(),
url = options.url,
type = options.type,
async = options.async || true,
// blob or arraybuffer. Default is blob
dataType = options.responseType || "blob",
data = options.data || null,
username = options.username || null,
password = options.password || null;
xhr.addEventListener('load', function () {
var data = {};
data[options.dataType] = xhr.response;
// make callback and send data
callback(xhr.status, xhr.statusText, data, xhr.getAllResponseHeaders());
});
xhr.open(type, url, async, username, password);
// setup custom headers
for (var i in headers) {
xhr.setRequestHeader(i, headers[i]);
}
xhr.responseType = dataType;
xhr.send(data);
},
abort: function () {
jqXHR.abort();
}
};
}
});
2. 第二步:使用此传输类型发出请求。
function downloadArt(url)
{
$.ajax(url, {
dataType: "binary",
processData: false
}).done(function (data) {
// just my logic to name/create files
var filename = url.substr(url.lastIndexOf('/') + 1) + '.png';
var blob = new Blob([data], { type: 'image/png' });
saveAs(blob, filename);
});
}
现在你可以使用创建的Blob,在我的情况下,我想把它保存到磁盘上。
3.可选:使用FileSaver将文件保存在用户计算机上
我已经使用filesver .js保存到磁盘下载的文件,如果你需要完成这一点,请使用这个javascript库:
https://github.com/eligrey/FileSaver.js/
我希望这能帮助其他有更具体需求的人。
查看从XHR请求中获取BLOB数据,指出BlobBuilder在Chrome中不工作,所以你需要使用:
xhr.responseType = 'arraybuffer';
正如gengkev在他的评论中提到的,看起来最好/唯一的方法是使用异步xhr2调用:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'blob:http%3A//your.blob.url.here', true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status == 200) {
var myBlob = this.response;
// myBlob is now the blob that the object URL pointed to.
}
};
xhr.send();
更新(2018):对于可以安全使用ES5的情况,Joe在下面给出了一个更简单的基于ES5的答案。
按照@Kaiido的回答,另一种重载URL而不搞乱URL的方法是像这样扩展URL类:
export class URLwithStore extends URL {
static createObjectURL(blob) {
const url = super.createObjectURL(blob);
URLwithStore.store = { ...(URLwithStore.store ?? {}), [url]: blob };
return url;
}
static getFromObjectURL(url) {
return (URLwithStore.store ?? {})[url] ?? null;
}
static revokeObjectURL(url) {
super.revokeObjectURL(url);
if (
new URL(url).protocol === "blob:" &&
URLwithStore.store &&
url in URLwithStore.store
)
delete URLwithStore.store[url];
}
}
使用
const blob = new Blob( ["foo"] );
const url = URLwithStore.createObjectURL( blob );
const retrieved = URLwithStore.getFromObjectURL( url );
console.log( "retrieved Blob is Same Object?", retrieved === blob );
使用fetch的例子如下所示:
fetch(<"yoururl">, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + <your access token if need>
},
})
.then((response) => response.blob())
.then((blob) => {
// 2. Create blob link to download
const url = window.URL.createObjectURL(new Blob([blob]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', `sample.xlsx`);
// 3. Append to html page
document.body.appendChild(link);
// 4. Force download
link.click();
// 5. Clean up and remove the link
link.parentNode.removeChild(link);
})
您可以粘贴在Chrome控制台进行测试。下载的文件是“sample.xlsx”,希望对大家有所帮助!