Javascript 从输入表单获取Base64编码文件数据
我有一个基本的HTML表单,我可以从中获取一些我正在Firebug中检查的信息 我唯一的问题是,我正在尝试对文件数据进行编码,然后再将其发送到服务器,服务器要求文件数据以该格式保存到数据库中Javascript 从输入表单获取Base64编码文件数据,javascript,html,file-upload,base64,Javascript,Html,File Upload,Base64,我有一个基本的HTML表单,我可以从中获取一些我正在Firebug中检查的信息 我唯一的问题是,我正在尝试对文件数据进行编码,然后再将其发送到服务器,服务器要求文件数据以该格式保存到数据库中 <input type="file" id="fileupload" /> 我有一些基于可用javascript的操作:.getAsBinary(),.getAsText(),.getAsTextURL 但是,这些文件都不会返回可插入的可用文本,因为它们
<input type="file" id="fileupload" />
我有一些基于可用javascript的操作:.getAsBinary(),.getAsText(),.getAsTextURL
但是,这些文件都不会返回可插入的可用文本,因为它们包含不可用的“字符”-我不想在上传的文件中出现“回发”,我需要有多个针对特定对象的表单,因此获取文件并以这种方式使用Javascript很重要
我应该如何获得文件,以便使用广泛可用的Javascript base64编码器之一
谢谢
更新-从这里开始赏金,需要跨浏览器支持!!!
这就是我现在的处境:
此外,IE不支持:
var file = $j(fileUpload.toString()).attr('files')[0];
因此,我必须用以下内容替换:
var element = 'id';
var element = document.getElementById(id);
为IE提供支持
这适用于Firefox、Chrome和Safari(但没有正确编码文件,或者至少在文件发布后,文件不会正确显示)
而且
似乎只有HTML5支持
很多人建议:
但这只会在UTF_8方法base64编码之前返回一个错误?(或空字符串)
在浏览器端javascript中,这是完全可能的 简单的方法: 该方法可能已经为您将其编码为base64。您可能需要去掉开头的内容(直到第一个
,
),但这没什么大不了的。不过,这会让所有的乐趣消失
艰难之路:
如果您想尝试这种方法(或者它不起作用),请查看readAsArrayBuffer()
。这将为您提供一个Uint8Array,您可以使用指定的方法。这可能只有在您想要处理数据本身时才有用,例如在上载之前操纵图像数据或执行其他巫毒魔法
有两种方法:
- 转换为字符串并使用内置的
或类似工具btoa
- 我并没有测试所有的案例,但对我来说很有效——只需获取字符代码即可
- 直接从UINT8阵列转换为base64
函数uint8ToString(buf){
变量i,长度,out='';
对于(i=0,长度=buf.length;i
从那里开始,只需:
var base64=btoa(uint8ToString(yourUint8Array))代码>
Base64现在将是一个Base64编码的字符串,它应该只上传peachy。如果要在推送之前再次检查,请尝试此操作:
window.open(“数据:应用程序/八位字节流;base64,”+base64)代码>
这将作为文件下载
其他信息:
要以Uint8Array的形式获取数据,请查看MDN文档:
我开始认为使用“iframe”进行Ajax风格的上传对于我来说可能是一个更好的选择,直到HTML5完全成熟,我的应用程序中不必支持传统浏览器 在自己努力解决这个问题之后,我开始为支持它的浏览器(Chrome、Firefox和尚未发布的Safari 6)实现FileReader,以及一个PHP脚本,该脚本将发布的文件数据作为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回答的启发:
constfiletobase64=异步(文件)=>
新承诺((解决、拒绝)=>{
const reader=new FileReader()
reader.readAsDataURL(文件)
reader.onload=()=>解析(reader.result)
reader.onerror=(e)=>拒绝(e)
})
const file=event.srcmelement.files[0];
const imageStr=wait fileToBase64(文件)
完整示例
Html文件输入
你在上传什么?文本数据还是二进制数据?@tjamenson二进制数据——任何真正的“word文档”“pdf”“图像”等。我本来打算在另一个变量中分配文件名,但我开始怀疑,在我对上传表单和html可能实现的功能的理解中,是否存在致命缺陷——这种方法完全不可行,也不可能传输文件数据通过将其作为字符串发布?我正在阅读的HTML5也有一些解决方案——很有趣。为什么要在浏览器和服务器之间进行base-64编码,并试图在浏览器中实现这一点?似乎如果您试图保护数据,SSL会更容易,因为它通过网络对所有HTTP数据(包括文件)进行加密。如果您的数据库需要,您可以在base-64服务器端进行加密。@William我不想保护数据,只需将其设置为正确的格式即可。Salesforce.com(Apex平台)要求在数据库中创建记录之前对数据库base64进行编码,它们通过表单对文件数据进行base64编码的功能的文档记录非常差(我在问了这个问题后知道了如何做到这一点)。无论如何,看起来base64编码二进制文件数据只在HTML5或Mozilla文件APIOK中本机支持,现在我明白为什么需要它了。没有中间服务器+疯狂的云需求+没有跨浏览器解决方案=1。抱歉,太好了--我以为readAsArrayBuffer()
会输出看起来正确的base64数据,但由于请求,它无法处理
var element = 'id';
var element = document.getElementById(id);
var file = $j(fileUpload.toString()).attr('files')[0];
var encoded = Btoa(file);
file.readAsArrayBuffer()
var encoded = Base64.encode(file);
function uint8ToString(buf) {
var i, length, out = '';
for (i = 0, length = buf.length; i < length; i += 1) {
out += String.fromCharCode(buf[i]);
}
return out;
}
$(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();
});
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');
};
}
<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>
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 as string);
reader.onerror = reject;
});
}