从 Input Form 获取 Base64编码文件数据

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

我唯一的问题是,我试图在将文件数据发送到服务器之前对其进行 < strong > base64 编码,因为要将文件数据以该格式保存到数据库,服务器就必须将其发送到服务器。

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

And in 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 would works in Firefox

此外,IE 不支持:

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

所以我必须用:

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

For IE Support.

这在 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。”

但是这只会在对 UTF _ 8方法执行 base64编码之前返回一个错误(或者一个空字符串)

var encoded = Base64.encode(file);
324977 次浏览

这在浏览器端的 javascript 中是完全可能的。

简单的方法:

ReadAsDataURL ()方法可能已经为您将其编码为 base64。您可能需要删除开始部分(直到第一个 ,) ,但这没什么大不了的。不过这样就没意思了。

艰难的道路:

如果你想尝试困难的方法(或者它不工作) ,看看 readAsArrayBuffer()。这将为您提供一个 Uint8Array,您可以使用指定的方法。这可能只有在您想要干扰数据本身时才有用,例如在您上传之前操作图像数据或者使用其他巫术。

有两种方法:

  • 转换为字符串并使用内置的 btoa或类似的
    • 我没有测试所有的情况下,但为我工作-只要得到字符代码
  • 直接从 Uint8Array 转换为 base64

I recently implemented 在浏览器中的 tar. As part of that process, I made my own direct Uint8Array->base64 implementation. I don't think you'll need that, but it's here if you want to take a look; it's pretty neat.

我现在要做的是:

从 Uint8Array 转换为 string 的代码非常简单(其中 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 文档:

我已经开始考虑使用“ iframe”进行 Ajax 风格的上传可能是我的情况下更好的选择,直到 HTML5完全恢复,我不必在我的应用程序中支持遗留浏览器!

经过自己的努力,我已经开始为支持 FileReader 的浏览器(Chrome,Firefox 和尚未发布的 Safari 6)实现 FileReader,并为其他浏览器实现一个 PHP 脚本,该脚本回应 POST 文件数据作为 Base64编码的数据。

我使用 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();
});

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

受@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)

完整的例子

HTML 文件输入

<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>

JS Handler

document.getElementById("upload-photo").addEventListener("change", function({target}){
if (target.files && target.files.length) {
try {
const uploadedImageBase64 = await convertFileToBase64(target.files[0]);
//do something with above data string
} catch() {
//handle error
}
}
})


function convertFileToBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
// Typescript users: use following line
// reader.onload = () => resolve(reader.result as string);
reader.onerror = reject;
});
}

那么为什么您不同意系统的用户从已知文件夹中选择一个图像呢?或者他们可以为图像设置他们的选择文件夹。

大多数浏览器不支持完整路径,但是你可以得到文件名,例如“ image.png”

Using PHP inbuilt function to encode:

@$picture_base64 = base64_encode( file_get_contents($image_file_name)  );

如果没有找到路径,符号@将抑制错误,但是变量 $picture _ base64的结果将是 null,所以我猜你可以使用 null,就像我在继续之前检查 null 一样。

在 html 中,您可以选择一个图像文件名作为输入,例如“ image.png”(但不是完整路径)

<input type="file" name="image" id="image" >

然后在 PHP 中你可以做:

$path = "C:\\users\\john\\Desktop\\images\\"
@$picture_base64 = base64_encode( file_get_contents( $path. $_POST['image']);

然后 $picture _ base64将类似于

"AQAAAAMAAAAHAAAADwAAAB8AAAA/AAAAfwAAAP8AAAD/AQAA/w"