我正在开发一个应用程序(在Node.js中,与此案例无关),允许用户上传图像。使用带有输入(type =“file”)字段的表单可以正常工作。
但是,我想要的是能够使用HTML5拖放来上传图像。就我而言,可以将图像拖到客户端,图像缩略图显示在div中。但是我真的需要一些帮助才能使文件上传工作。
问题是我想使用我现在正在使用的表单,并且(不知何故)将文件的路径传递给输入字段,即流程将完全像现在一样工作,而不是选择通过浏览文件我想通过拖放将它附加到输入字段。
在下面用于拖放的js代码中,拖动到客户端的文件存储在变量“file”中,我可以使用“file.name”,“file.type”和“file” .size“与之前的表单完全相同。但是,我无法访问文件“path”(file.path),这使得无法访问文件服务器端进行上传,就像之前一样。
问题是,在将文件拖到客户端后,是否可以将文件对象传递到输入字段,以便我可以单击“提交”并上传文件?如果是这样,怎么办呢?
提前致谢!
Dropbox以及我用于文件上传的表单:
<div id='upload'>
<article>
<div id='holder'>
<p id='status'>File API and FileReader API not supported</p>
</div>
</article>
<form method='post' enctype='multipart/form-data' action='/file-upload'>
<p>
<input type='file' name='thumbnail'>
</p>
<p>
<input type='submit'>
</p>
</form>
</div>
拖放代码:
uploadImage: function(){
var holder = document.getElementById('holder'),
state = document.getElementById('status');
if (typeof window.FileReader === 'undefined') {
state.className = 'fail';
} else {
state.className = 'success';
state.innerHTML = 'File API & FileReader available';
}
holder.ondragover = function () { this.className = 'hover'; return false; };
holder.ondragend = function () { this.className = ''; return false; };
holder.ondrop = function (e) {
this.className = '';
e.preventDefault();
var file = e.dataTransfer.files[0],
reader = new FileReader();
reader.onload = function (event) {
holder.style.background = 'url(' + event.target.result + ') no-repeat center';
};
reader.readAsDataURL(file);
return false;
};
},
答案 0 :(得分:8)
您无法使用文件输入添加文件数据。 然而,你可以做的(除了其他技术之外)是使用base64(当使用 readAsDataURL 方法时,通过reader.onload事件本身可用作 event.target.result )编码数据并将其放入隐藏字段:
HTML
<article>
<div id='holder'>
<p id='status'>File API and FileReader API not supported</p>
</div>
</article>
<form method='post' enctype='multipart/form-data' action='/file-upload'>
<input type='file' name='thumbnail' />
<input type='hidden' name='base64data' />
<input type='submit' formenctype='application/x-www-form-urlencoded' />
</form>
JS
reader = new FileReader();
reader.onload = function (event) {
document.getElementById('base64data').setAttribute('value', event.target.result);
};
reader.readAsDataURL(file);
从服务器端,您将能够从文件中获取base64编码数据,只需对其进行解码并根据需要使用它。
在提交表单时,您还可以更改“enctype”属性(通过 formenctype 属性完成)并删除基本的html文件输入,因为数据将在文本字段中发布。
答案 1 :(得分:0)
出于安全目的,无法知道该字段的路径。通过拖放,您必须独立于主窗体上载它。在这里查看示例:http://www.sitepoint.com/html5-file-drag-and-drop/
答案 2 :(得分:0)
我发现后面的代码中未设置reader.onload中设置的隐藏字段(请参阅@challet的答案)。我正在使用asp.net和一个WebForms项目。要访问隐藏的字段,我必须在MainContent_之前添加字段名称。 aspx代码在下面
<asp:Content ID="Content3" ContentPlaceHolderID="MainContent" runat="server">
...
<script type="text/javascript">
function dropHandler(ev) {
alert("File(s) dropped");
// Prevent default behavior (Prevent file from being opened)
ev.preventDefault();
//alert("Default prevented");
if (ev.dataTransfer.items) {
if (ev.dataTransfer.items.length > 1) {
alert("Only single files can be dragged and dropped into Caption Pro Web");
return;
}
// If dropped items aren't files, reject them
if (ev.dataTransfer.items[0].kind === 'file') {
var file = ev.dataTransfer.items[0].getAsFile();
document.getElementById("MainContent_DroppedFileName").value = ev.dataTransfer.items[0].name
reader = new FileReader();
reader.onload = function (event) {
document.getElementById('MainContent_DroppedFileContent').value = event.target.result;
};
reader.readAsDataURL(ev.dataTransfer.items[0]);
}
} else {
// Use DataTransfer interface to access the file(s)
if (ev.dataTransfer.files.length > 1) {
alert("Only single files can be dragged and dropped into Caption Pro Web");
return;
}
document.getElementById("MainContent_DroppedFileName").value = ev.dataTransfer.files[0].name
document.getElementById("MainContent_DroppedFileContent").value = "Test";
reader = new FileReader();
reader.onload = function (event) {
document.getElementById("MainContent_DroppedFileContent").value = event.target.result;
};
reader.readAsDataURL(ev.dataTransfer.files[0]);
}
document.getElementById('<%=btnDrop.ClientID %>').click();
}
</script>
...
<div id="drop_zone" ondrop="dropHandler(event);" ondragover="dragOverHandler(event);">
<p>Drag image to this Drop Zone ...</p>
</div>
<asp:HiddenField ID="DroppedFileName" runat="server" />
<asp:HiddenField ID="DroppedFileContent" runat="server" />
...
</asp:Content>
我从c#访问隐藏字段,如下所示
protected void btnDrop_Click(object sender, EventArgs e)
{
string FileName = DroppedFileName.Value;
string FileContent = DroppedFileContent.Value;
}
如果我使用Internet Explorer作为目标浏览器(不以管理员身份运行VS,因为这将禁用拖放操作!)并在reader.onload()函数中设置断点,则隐藏字段DroppedFileContent包含编码的文件内容,但是当我尝试从btnDrop_Click访问它,它仅包含reader.onload()之前设置的“测试”,并且不包含编码的文件内容。字段DroppedFileNam.Value与Javascript中的设置相同。