개체 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.