Javascript 如何从对象 URL 获取文件或 blob?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11876175/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get a file or blob from an object URL?
提问by BrianFreud
I am allowing the user to load images into a page via drag&drop and other methods. When an image is dropped, I'm using URL.createObjectURL
to convert to an object URL to display the image. I am not revoking the url, as I do reuse it.
我允许用户通过拖放和其他方法将图像加载到页面中。放置图像时,我使用URL.createObjectURL
转换为对象 URL 以显示图像。我不会撤销 url,因为我会重用它。
So, when it comes time to create a FormData
object so I can allow them to upload a form with one of those images in it, is there some way I can then reverse that Object URL back into a Blob
or File
so I can then append it to a FormData
object?
所以,当谈到时间来创建一个FormData
对象,所以我可以让他们上传的形式,在它的形象之一,是有一些方法,然后我可以扭转这一目标URL回一个Blob
或File
这样我就可以再附加到一个FormData
目的?
采纳答案by BrianFreud
Modern solution:
现代解决方案:
let blob = await fetch(url).then(r => r.blob());
The url can be an object url or a normal url.
url 可以是对象 url 或普通 url。
回答by BrianFreud
As gengkev alludes to in his comment above, it looks like the best/only way to do this is with an async xhr2 call:
正如 gengkev 在他上面的评论中提到的,看起来最好/唯一的方法是使用 async 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();
Update (2018): For situations where ES5 can safely be used, Joe has a simpler ES5-based answer below.
更新(2018 年):对于可以安全使用 ES5 的情况,Joe 在下面有一个更简单的基于 ES5 的答案。
回答by spedy
Maybe someone finds this useful when working with React/Node/Axios. I used this for my Cloudinary image upload feature with react-dropzone
on the UI.
也许有人在使用 React/Node/Axios 时发现这很有用。我react-dropzone
在 UI上将其用于 Cloudinary 图像上传功能。
axios({
method: 'get',
url: file[0].preview, // blob url eg. blob:http://127.0.0.1:8000/e89c5d87-a634-4540-974c-30dc476825cc
responseType: 'blob'
}).then(function(response){
var reader = new FileReader();
reader.readAsDataURL(response.data);
reader.onloadend = function() {
var base64data = reader.result;
self.props.onMainImageDrop(base64data)
}
})
回答by user3843418
Using fetch for example like below:
使用 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);
})
You can paste in on Chrome console to test. the file with download with 'sample.xlsx' Hope it can help!
您可以粘贴到 Chrome 控制台进行测试。带有'sample.xlsx'的下载文件希望它可以帮助!
回答by Michel Floyd
See Getting BLOB data from XHR requestwhich points out that BlobBuilder doesn't work in Chrome so you need to use:
请参阅从 XHR 请求中获取 BLOB 数据,其中指出 BlobBuilder 在 Chrome 中不起作用,因此您需要使用:
xhr.responseType = 'arraybuffer';
回答by Wagner Bertolini Junior
Unfortunately @BrianFreud's answer doesn't fit my needs, I had a little different need, and I know that is not the answer for @BrianFreud's question, but I am leaving it here because a lot of persons got here with my same need. I needed something like 'How to get a file or blob from an URL?', and the current correct answer does not fit my needs because its not cross-domain.
不幸的是,@BrianFreud 的回答不符合我的需求,我有一点不同的需求,我知道这不是@BrianFreud 问题的答案,但我将它留在这里是因为很多人带着我同样的需求来到这里。我需要诸如“如何从 URL 获取文件或 blob?”之类的内容,而当前的正确答案不符合我的需求,因为它不是跨域的。
I have a website that consumes images from an Amazon S3/Azure Storage, and there I store objects named with uniqueidentifiers:
我有一个使用 Amazon S3/Azure 存储中的图像的网站,我在那里存储以 uniqueidentifiers 命名的对象:
sample: http://****.blob.core.windows.net/systemimages/bf142dc9-0185-4aee-a3f4-1e5e95a09bcf
示例:http://****.blob.core.windows.net/systemimages/bf142dc9-0185-4aee-a3f4-1e5e95a09bcf
Some of this images should be download from our system interface. To avoid passing this traffic through my HTTP server, since this objects does not require any security to be accessed (except by domain filtering), I decided to make a direct request on user's browser and use local processing to give the file a real name and extension.
其中一些图像应该从我们的系统界面下载。为了避免通过我的 HTTP 服务器传递这个流量,因为这个对象不需要任何安全性来访问(除了域过滤),我决定在用户的浏览器上直接请求并使用本地处理给文件一个真实的名字和延期。
To accomplish that I have used this great article from Henry Algus: http://www.henryalgus.com/reading-binary-files-using-jquery-ajax/
为了实现这一点,我使用了 Henry Algus 的这篇很棒的文章:http: //www.henryalgus.com/reading-binary-files-using-jquery-ajax/
1. First step: Add binary support to jquery
1.第一步:为jquery添加二进制支持
/**
*
* jquery.binarytransport.js
*
* @description. jQuery ajax transport for making binary data type requests.
* @version 1.0
* @author Henry Algus <[email protected]>
*
*/
// 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. Second step: Make a request using this transport type.
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);
});
}
Now you can use the Blob created as you want to, in my case I want to save it to disk.
现在您可以根据需要使用创建的 Blob,在我的情况下,我想将其保存到磁盘。
3. Optional: Save file on user's computer using FileSaver
3. 可选:使用 FileSaver 在用户计算机上保存文件
I have used FileSaver.js to save to disk the downloaded file, if you need to accomplish that, please use this javascript library:
我已经使用 FileSaver.js 将下载的文件保存到磁盘,如果你需要完成,请使用这个 javascript 库:
https://github.com/eligrey/FileSaver.js/
https://github.com/eligrey/FileSaver.js/
I expect this to help others with more specific needs.
我希望这可以帮助有更具体需求的其他人。
回答by Thilo
If you show the file in a canvas anyway you can also convert the canvas content to a blob object.
如果您无论如何都在画布中显示文件,您还可以将画布内容转换为 blob 对象。
canvas.toBlob(function(my_file){
//.toBlob is only implemented in > FF18 but there is a polyfill
//for other browsers https://github.com/blueimp/JavaScript-Canvas-to-Blob
var myBlob = (my_file);
})