입력 양식에서 Base64 인코딩 파일 데이터 가져 오기


100

Firebug에서 조사중인 약간의 정보를 얻을 수있는 기본 HTML 양식이 있습니다.

내 유일한 문제는 데이터베이스에 저장하기 위해 해당 형식으로 있어야하는 서버로 전송되기 전에 파일 데이터 를 base64로 인코딩 하려고한다는 것 입니다.

<input type="file" id="fileupload" />

그리고 Javascript + jQuery에서 :

var file = $('#fileupload').attr("files")[0];

사용 가능한 자바 스크립트를 기반으로 몇 가지 작업이 있습니다. .getAsBinary (), .getAsText (), .getAsTextURL

그러나 이들 중 어느 것도 사용할 수없는 '문자' 를 포함하고 있기 때문에 삽입 할 수있는 사용 가능한 텍스트를 반환 하지 않습니다. 업로드 된 파일에 '포스트 백'이 발생하지 않도록하고 특정 개체를 대상으로하는 여러 양식이 필요하므로 중요합니다. 이 방법으로 파일을 얻고 Javascript를 사용하십시오.

널리 사용되는 Javascript base64 인코더 중 하나를 사용할 수 있도록 파일을 어떻게 가져와야합니까!?

감사

업데이트-여기에서 현상금을 시작하려면 브라우저 간 지원이 필요합니다 !!!

내가있는 곳은 다음과 같습니다.

<input type="file" id="fileuploadform" />

<script type="text/javascript">
var uploadformid = 'fileuploadform';
var uploadform = document.getElementById(uploadformid);


/* method to fetch and encode specific file here based on different browsers */

</script>

크로스 브라우저 지원과 관련된 몇 가지 문제 :

var file = $j(fileUpload.toString()).attr('files')[0];
fileBody = file.getAsDataURL(); // only would works in Firefox

또한 IE는 다음을 지원하지 않습니다.

var file = $j(fileUpload.toString()).attr('files')[0];

그래서 다음으로 교체해야합니다.

var element = 'id';
var element = document.getElementById(id);

IE 지원용.

이것은 Firefox, Chrome 및 Safari에서 작동합니다 (하지만 파일을 올바르게 인코딩하지 않거나 적어도 게시 된 후에 파일이 제대로 나오지 않음)

var file = $j(fileUpload.toString()).attr('files')[0];
var encoded = Btoa(file);

또한,

file.readAsArrayBuffer() 

HTML5에서만 지원되는 것 같습니까?

많은 사람들이 제안했습니다 : http://www.webtoolkit.info/javascript-base64.html

그러나 이것은 base64로 인코딩하기 전에 UTF_8 메서드에서 오류 만 반환합니까? (또는 빈 문자열)

var encoded = Base64.encode(file); 

무엇을 업로드하고 있습니까? 텍스트 데이터 또는 바이너리?
beatgammit

@tjamenson 바이너리 데이터-무엇이든 '단어 문서' 'pdf' '이미지'등. 다른 변수에 파일 이름을 할당하려고했지만 무엇을 할 수 있는지 이해하는 데 치명적인 결함이 있는지 궁금해지기 시작했습니다. 양식 및 HTML 업로드-이 방법은 완전히 실행 불가능하며 문자열로 게시하여 파일 데이터를 전송할 수 없습니까? - 또한 HTML5없이 내가 읽고 몇 가지 솔루션을 보유하고있어 어느
jordan.baucke

흥미 롭군. 브라우저와 서버간에 Base-64 인코딩을 수행하는 이유는 무엇이며 브라우저에서이를 수행하려고합니까? 데이터를 보호하려는 경우 SSL은 유선을 통해 모든 HTTP 데이터 (파일 포함)를 암호화하므로 훨씬 쉬울 것이며 데이터베이스에 필요한 경우 base-64 서버 측을 사용할 수 있습니다.
William Walseth 2011-08-24

@William 나는 데이터를 보호하려는 것이 아니라 올바른 형식으로 가져옵니다. Salesforce.com (Apex 플랫폼)에서는 데이터베이스에 레코드가 생성되기 전에 base64로 인코딩 된 데이터베이스가 필요합니다 . 양식을 통해 파일 데이터를 base64로 인코딩 하는 기능 은 매우 제대로 문서화되어 있지 않습니다 (이 질문을 한 후이 작업을 수행하는 방법을 알아 냈습니다). 어쨌든 base64 인코딩 바이너리 파일 데이터는 HTML5 또는 Mozilla 파일 API
jordan.baucke

1
좋아, 이제 왜 이것이 필요한지 알 수 있습니다. 중간 서버 없음 + 미친 클라우드 요구 사항 + 크로스 브라우저 솔루션 없음 = 혼란 1 개. 죄송합니다.
William Walseth 2011 년

답변:


121

브라우저 측 자바 스크립트에서는 전적으로 가능합니다.

쉬운 방법 :

readAsDataURL () 메소드는 이미 당신을위한베이스 64로 인코딩 할 수 있습니다. 아마도 처음부터 제거해야 할 필요가있을 것입니다 (첫 번째까지). 그러나 그것은 큰 문제가 아닙니다. 이것은 모든 재미를 가져갈 것입니다.

어려운 방법:

어려운 방법으로 시도하고 싶다면 (또는 작동하지 않는 경우) readAsArrayBuffer() . 그러면 Uint8Array가 제공되고 지정된 메서드를 사용할 수 있습니다. 이것은 업로드하기 전에 이미지 데이터를 조작하거나 다른 부두 마술을하는 것과 같이 데이터 자체를 엉망으로 만들고 싶을 때만 유용 할 것입니다.

두 가지 방법이 있습니다.

  • 문자열로 변환하고 내장 된 사용 btoa 또는 유사 사용
    • 모든 경우를 테스트하지는 않았지만 나를 위해 작동합니다. 문자 코드 만 가져옵니다.
  • Uint8Array에서 base64로 직접 변환

최근 에 브라우저에서 tar를 구현 했습니다 . 이 프로세스의 일부로 직접 Uint8Array-> base64 구현을 만들었습니다. 나는 당신이 그것을 필요로하지 않을 것이라고 생각하지만, 당신이보고 싶다면 여기 에 있습니다. 꽤 깔끔합니다.

내가 지금하는 일 :

Uint8Array에서 문자열로 변환하는 코드는 매우 간단합니다 (buf는 Uint8Array 임).

function uint8ToString(buf) {
    var i, length, out = '';
    for (i = 0, length = buf.length; i < length; i += 1) {
        out += String.fromCharCode(buf[i]);
    }
    return out;
}

거기에서 다음을 수행하십시오.

var base64 = btoa(uint8ToString(yourUint8Array));

Base64는 이제 base64로 인코딩 된 문자열이되며 복숭아 만 업로드해야합니다. 푸시하기 전에 다시 확인하려면 다음을 시도하십시오.

window.open("data:application/octet-stream;base64," + base64);

파일로 다운로드됩니다.

기타 정보 :

데이터를 Uint8Array로 가져 오려면 MDN 문서를 참조하십시오.


훌륭합니다- readAsArrayBuffer()올바른 base64 데이터 처럼 보이는 출력을 생각 했지만 문자열의 구걸 부분 때문에 처리되지 않을 것입니다-지금 시도해 보겠습니다!
jordan.baucke 2011 년

1
readAsArrayBuffer ()는 Chrome / Safari에 존재하지 않는 것 같고 다른 브라우저에서 문제가 될 것이라고 가정하고 있습니다 ~ 이러한 다른 브라우저에서 사용할 수있는 동등한 기능이 있습니까?
jordan.baucke

createObjectURL () <-이것은 내가 그것을 구현하려고 시도 할 것 같지만 IE는 세 번째 바퀴가 필요할 것이라고 확신합니다
jordan.baucke 2011 년

다운로드 솔루션을 실행하기 전에 파일 이름을 지정할 수 있습니까?
Ωmega

@ Ωmega-아니요.이 모든 작업은 바이너리 스트림을 다운로드하는 것입니다. 파일 이름을 지정할 수있는 방법 (AFAIK)은 없습니다. 일부 브라우저는 확장 기능을 추측합니다. 파일 이름을 얻으려면 업로드 한 다음 다시 다운로드해야합니다.
beatgammit 2013

37

내 해결책은 사용 readAsBinaryString()btoa()그 결과였습니다.

uploadFileToServer(event) {
    var file = event.srcElement.files[0];
    console.log(file);
    var reader = new FileReader();
    reader.readAsBinaryString(file);

    reader.onload = function() {
        console.log(btoa(reader.result));
    };
    reader.onerror = function() {
        console.log('there are some problems');
    };
}

3
가장 쉬운 방법은 왜 더 많은 표를 가지고 있지 않습니까?
sarink

14

Ajax 요청을 사용하지 않고 파일 업로드 버튼을 클릭하면 FileReader를 사용하여 이미지를 표시했습니다. 다음은 코드가 도움이 될 수 있기를 바랍니다.

$(document).ready(function($) {
    $.extend( true, jQuery.fn, {        
        imagePreview: function( options ){          
            var defaults = {};
            if( options ){
                $.extend( true, defaults, options );
            }
            $.each( this, function(){
                var $this = $( this );              
                $this.bind( 'change', function( evt ){

                    var files = evt.target.files; // FileList object
                    // Loop through the FileList and render image files as thumbnails.
                    for (var i = 0, f; f = files[i]; i++) {
                        // Only process image files.
                        if (!f.type.match('image.*')) {
                        continue;
                        }
                        var reader = new FileReader();
                        // Closure to capture the file information.
                        reader.onload = (function(theFile) {
                            return function(e) {
                                // Render thumbnail.
                                    $('#imageURL').attr('src',e.target.result);                         
                            };
                        })(f);
                        // Read in the image file as a data URL.
                        reader.readAsDataURL(f);
                    }

                });
            });
        }   
    });
    $( '#fileinput' ).imagePreview();
});

1

이 문제를 직접 해결 한 후,이를 지원하는 브라우저 (Chrome, Firefox 및 아직 출시되지 않은 Safari 6)를위한 FileReader를 구현하고, POST 된 파일 데이터를 Base64로 인코딩 된 데이터로 다시 에코하는 PHP 스크립트를 구현했습니다. 브라우저.


0

Ajax 스타일 업로드에 'iframe'을 사용하는 것이 HTML5 가 완전히 원을 그리며 내 앱에서 레거시 브라우저를 지원할 필요가 없을 때까지 내 상황에 훨씬 더 나은 선택이 될 것이라고 생각하기 시작했습니다 !


궁금한 점이 있습니다. [ webtoolkit.info/javascript-base64.html#]을 가져간 다음 주석 처리 input = Base64._utf8_encode(input);하고 output = Base64._utf8_decode(output);? utf-8 변환 오류 이외의 문제가 있습니까?
shr aug

@shr 각 브라우저에서 이러한 메서드에 입력하기 위해 이진 파일 데이터를 가져 오는 방법을 모르겠습니까? $('#inputid').files[0]( 내가 말할 수 있는 한 IE7에서는 작동하지 않습니다 ). 그렇게 쉬웠다면? var output = Base64.encode($('#inputid').files[0])??
jordan.baucke 2011-08-24

0

@Josef의 답변에서 영감을 얻었습니다.

const fileToBase64 = async (file) =>
  new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.readAsDataURL(file)
    reader.onload = () => resolve(reader.result)
    reader.onerror = (e) => reject(e)
  })

const file = event.srcElement.files[0];
const imageStr = await fileToBase64(file)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.