从输入表单获取Base64编码文件数据

时间:2011-08-08 05:43:18

标签: javascript html file-upload base64

我有一个基本的HTML表单,我可以从中获取一些我在Firebug中检查的信息。

我唯一的问题是我正在尝试 base64 对文件数据进行编码,然后将其发送到服务器,并将其保存到该表单中数据库。

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

在Javascript + jQuery中:

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

我有一些基于可用javascript的操作: .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 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); 

7 个答案:

答案 0 :(得分:112)

完全有可能在浏览器端javascript。

简单方法:

readAsDataURL()方法可能已经为您编码为base64。你可能需要去除开始的东西(直到第一个),但这并不重要。这会带来所有乐趣。

艰难的方式:

如果你想以艰难的方式尝试(或者它不起作用),请查看readAsArrayBuffer()。这将为您提供Uint8Array,您可以使用指定的方法。这可能仅在您想要混淆数据本身时才有用,例如在上传之前操纵图像数据或执行其他巫术魔术。

有两种方法:

  • 转换为字符串并使用内置btoa或类似内容
    • 我没有测试过所有案例,但对我有用 - 只需获取char-codes
  • 直接从Uint8Array转换为base64

我最近实施了tar in the browser。作为该过程的一部分,我自己制作了直接的Uint8Array-&gt; base64实现。我不认为你需要那个,但是如果你想看看它是here;它非常整洁。

我现在做什么:

从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编码的字符串,它应该只上传peachy。如果您想在推送前仔细检查,请尝试此操作:

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

这会将其下载为文件。

其他信息:

要将数据作为Uint8Array获取,请查看MDN文档:

答案 1 :(得分:22)

我的解决方案是在结果上使用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');
    };
}

答案 2 :(得分:14)

我使用FileReader在单击文件上传按钮时显示图像而不使用任何Ajax请求。以下是代码希望它可以帮助一些人。

$(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();
});

答案 3 :(得分:1)

在我自己挣扎之后,我开始为支持它的浏览器(Chrome,Firefox和尚未发布的Safari 6)实现FileReader,以及一个回送POST文件数据作为Base64编码数据的PHP脚本对于其他浏览器。

答案 4 :(得分:1)

灵感来自@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)

答案 5 :(得分:1)

完整示例

HTML 文件输入

item_number_list = [101,102,103,104,105,106,107,108,109,110]
description_list = ["3G Telecoms Licenses",
"UK Gold Reserves",
"Boeing C-17 Globemaster III",
"Les Femmes d'Alger by Pablo Picasso",
"Giacometti’s Pointing Man",
"Oppenheimer Blue",
"1962-63 Ferrari 250 GTO Berlinetta",
"The Clark Sickle-Leaf Carpet",
"The Codex Leicester by Leonardo da Vinci",
"Patek Philippe Wristwatch"]

JS 处理程序

<style>
.upload-button {
  background-color: grey;
}

.upload-button input{
  display:none;
}
</style>
<label for="upload-photo" class="upload-button">
    Upload file
    <input
     type="file"
     id="upload-photo"
    </input>
</label>

答案 6 :(得分:0)

我开始认为使用'iframe'进行Ajax样式上传对于我的情况可能是一个更好的选择,直到 HTML5 完整循环并且我不必支持旧版浏览器在我的应用程序!