개체 URL에서 파일 또는 Blob을 가져 오는 방법은 무엇입니까?


127

사용자가 끌어서 놓기 및 기타 방법을 통해 페이지에 이미지를로드 할 수 있습니다. 이미지가 드롭되면 이미지 URL.createObjectURL를 표시하기 위해 객체 URL로 변환하는 데 사용 합니다. 나는 그것을 재사용하기 때문에 URL을 취소하지 않습니다.

그것은 만들 수있는 시간이 온다 때, FormData나는 그들이 거기에 그 이미지 중 하나를 사용하여 양식을 업로드 할 수 있도록 할 수 있도록 객체를, 내가 다음에 그 개체의 URL 다시 반전 할 수있는 몇 가지 방법이있다 Blob또는 FileA를 다음 APPEND 그것이 내가 할 수 있도록이 FormData목적?


이전 두 주석에 대해서는 신경 쓰지 마십시오 XMLHttpRequest. blob URL 로 를 보내는 것뿐입니다.
gengkev

2
원본 파일 객체를 어딘가에 저장 한 다음 객체 URL을 사용하여 표시하고 양식 제출시 원본 파일을 사용하는 것이 어떻습니까?
user764754

@ user764754 파일의 URL을 얻으려고 노력하는 등 사용자의 표시가 업로드되고 있기 때문 "C : \ fakepath"
말콤 살바도르

답변:


88

최신 솔루션 :

let blob = await fetch(url).then(r => r.blob());

URL은 개체 URL 또는 일반 URL 일 수 있습니다.


3
좋은. ES5가 이와 같은 것을 더 간단하게 만드는 것을 보니 기쁩니다.
BrianFreud

11
Promise에서 직접 파일을 얻고 싶다면 다음과 같이 파일을 생성 할 수 있습니다. let file = await fetch(url).then(r => r.blob()).then(blobFile => new File([blobFile], "fileNameGoesHere", { type: "image/png" })
dbakiu

3
불행히도이 솔루션은 Chrome에서 작동하지 않습니다. 브라우저가이 URL을로드하지 못했습니다.
waldgeist

Waldgeist, createObjectUrl ()에 래핑 했습니까?
Matt Fletcher

73

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 기반 답변을 제공합니다.


19
현재 도메인 및 범위에 대해 로컬이 아닌 objectURL 을 언제 갖게 됩니까?
BrianFreud 2014 년

4
나는 위와 동일하게했지만 xhr에서 404를 찾지 못했습니다. 무슨 일이야?
albert yu

당신이 처리해야하는 경우 참고 일부 브라우저 (오래된 IE를 ... 읽기), 그 포스트를 참조하시기 바랍니다 stackoverflow.com/questions/17657184/...
mraxus

4
@BrianFreud "현재 도메인 및 범위에 대해 로컬이 아닌 objectURL을 언제 갖게 되었습니까?" 제 경우에는 Amazon S3 blob에 다른 파일 이름을 지정하려고합니다. 현재 확장명이없는 S3의 "guid"입니다. 그래서 제 경우에는 교차 도메인 호출을 사용하고 있습니다.
Wagner Bertolini Junior

6
"개체 URL은 디스크의 파일을 가리키는 URL입니다." 정의에 따른 ObjectURL은 로컬 일 수만 있습니다.
BrianFreud

12

누군가 React / Node / Axios로 작업 할 때 유용하다고 생각할 수 있습니다. react-dropzoneUI에서 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)
         }

    })

1
교차 도메인 요청에 대해 작동합니까? Twitter 비디오에는 BLOB URL이 있습니다. Blob URL이 가리키는 Blob 개체를 수집 할 수 있어야합니다. 브라우저에서 fetch api를 사용하고 있는데 이로 인해이 오류가 발생 Refused to connect to 'blob:https://twitter.com/9e00aec3-6729-42fb-b5a7-01f50be302fa' because it violates the following Content Security Policy directive: "connect-src 합니다. 내가 잘못하고 있거나 얻지 못할 수있는 힌트를 주실 수 있습니까?
gdadsriver

이 한 줄짜리를 사용하여 blob을 데이터 속성으로 사용하여 결과를 얻을 수있었습니다. const result = await axios.get (url, {responseType : "blob"});
Noah Stahl


4

예를 들어 아래와 같이 가져 오기를 사용합니다.

 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'로 다운로드 한 파일이 도움이되기를 바랍니다!


OP가 blob url을 다른 방법이 아닌 실제 파일 / blob으로 변환하는 것에 대해 물었다 고 생각합니다.
Abhishek Ghosh

3

불행히도 @BrianFreud의 대답은 내 요구에 맞지 않고 약간 다른 필요가 있었고 @BrianFreud의 질문에 대한 대답이 아니라는 것을 알고 있지만 많은 사람들이 내 필요로 여기에 왔기 때문에 여기에 남겨 둡니다. 나는 'URL에서 파일이나 blob을 얻는 방법'과 같은 것이 필요했고 현재 정답은 도메인 간이 아니기 때문에 내 요구에 맞지 않습니다.

Amazon S3 / Azure Storage의 이미지를 사용하는 웹 사이트가 있고 거기에 uniqueidentifiers라는 이름의 객체를 저장합니다.

샘플 : http : //****.blob.core.windows.net/systemimages/bf142dc9-0185-4aee-a3f4-1e5e95a09bcf

이 이미지 중 일부는 시스템 인터페이스에서 다운로드해야합니다. 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를 사용하여 사용자 컴퓨터에 파일 저장

FileSaver.js를 사용하여 다운로드 한 파일을 디스크에 저장했습니다. 필요한 경우 다음 자바 스크립트 라이브러리를 사용하세요.

https://github.com/eligrey/FileSaver.js/

나는 이것이 더 구체적인 필요를 가진 다른 사람들을 도울 것으로 기대합니다.


1
ObjectURL은 정의에 따라 로컬입니다. 개체 URL은 디스크의 파일을 가리키는 URL입니다. 교차 도메인 objectURL과 같은 것이 없다는 점을 감안할 때 두 가지 다른 개념을 결합하므로 주어진 솔루션을 사용하여 문제가 발생합니다.
BrianFreud

1
@BrianFreud 나는이 질문에 대한 답이 아닙니다. 그러나 나는 'URL에서 파일이나 blob을 얻는 방법'에 대한 약간 다른 질문에 대한 답을 찾고 있기 때문에 여전히 좋은 대답이라고 생각합니다. 자신의 답변을 확인하면 '도메인 간 요청시 작동하지 않습니다. '. 그래서 10 명 이상의 사람들이 그것을 찾고 있습니다. 나는 그것을 여기에두기로 결정했다.
Wagner Bertolini Junior

문제는 귀하의 답변이이 질문에 고의로 답변하지 않는다는 것입니다. 일반 URL과 개체 URL은 완전히 다른 두 가지입니다. "도메인 간 요청의 경우 작동하지 않습니다."에 대한 찬성 투표 수와 관련하여 여기에서 문자 그대로 불가능한 이유를 설명하고 일반 URL에 대한 답변을 표시하는 어딘가를 가리키는 것이 더 낫다고 생각하지 않습니까? 일반 URL과 개체 URL을 결합하여 여기에 혼란을주는 것보다
BrianFreud

@BrianFreud는 내 대답에 대한 편집을 자유롭게 제안하십시오. 주제에 대해 공부할 것입니다. "objectURL"과 "object URL"이 무엇인지 오해했을 수도 있습니다. 영어는 제 모국어가 아닙니다. 더 나은 답변을 드리기 위해 주제에 대해 조사하겠습니다. 그러나 나는 다른 것을 찾고있는 다른 사람들이라고 생각합니다. 여기에 도착하기 위해 "objectURL"을 검색하지 않았는데, 그게 이전에 내 요점이었습니다. 하지만 나도 잡았어.
Wagner Bertolini Junior

2

어쨌든 캔버스에 파일을 표시하는 경우 캔버스 콘텐츠를 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);
})

2
실제로 동일한 원본 파일 을 돌려주는 것은 아닙니다 . 즉석에서 새 이미지 파일을 만들고 있습니다. 몇 년 전에 마지막으로 테스트했을 때 최소한 Chrome에서는 새 이미지 파일이 전혀 압축되지 않았 음을 발견했습니다. 10k jpg가 2.5MB jpg로 바뀌 었습니다.
BrianFreud
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.