我正在尝试在后台上传文件。我无法使用任何框架,因此我必须手动完成。该页面已经包含一个表单,文件输入字段位于该表单中,因此我无法在表单中嵌入表单,因此我需要移动文件输入。
我正在使用的代码的问题是它似乎没有实际提交,我根本看不到任何网络活动。谁能在这里发现任何错误?
<form>
...
<input id="photo-file-input" type="file"/>
<button type="button" onClick="uploadBackground('photo-file-input');">Upload</button>
....
</form>
function uploadBackground(fileInputId)
{
var iframe = createIframe('TEST');
var form = createUploadForm('TEST', 'upload.php');
var fileInput = document.getElementById(fileInputId);
var fileInputParent = fileInput.parent;
//move file input into generated form
form.appendChild(fileInput);
form.submit();
iframe.onload = function()
{
alert('file was uploaded');
//put the file input back where it was
fileInputParent.appendChild(fileInput);
//clean up generated elements
iframe.parent.removeChild(iframe);
form.parent.removeChild(form);
}
}
function createUploadForm(target, action)
{
var form = document.createElement('form');
form.display = 'none';
form.target = target;
form.action = action;
form.method = 'POST';
form.enctype = 'multipart/form-data';
return form;
}
function createIframe(name)
{
var iframe;
try
{
iframe = document.createElement('<iframe name="' + name + '">');
}
catch (ex)
{
iframe = document.createElement('iframe');
iframe.name = name;
}
return iframe;
}
答案 0 :(得分:3)
您无法复制文件输入元素并设置/保留其值。这是出于安全原因。您没有理由需要创建新表单。只需将iframe附加到页面,将表单的目标设置为iframe名称并提交原始表单。
答案 1 :(得分:1)
我一直在寻找同样的问题,我想,我找到了一个解决方案,适用于Firefox和Chrome,可能在IE 10及以上版本(这里需要进行一些测试)
解决方案有点难看因为我使用了框架集。但这是我到目前为止找到的唯一解决方案。
用例是: 我们有一个包含产品目录的网站,编辑可以为每个产品上传视频。
视频上传需要很长时间,所以我一直在寻找解决方案,在您选择视频后开始上传,您可以导航到其他产品并上传其他文件,而无需等到第一个下载完成。
该测试基于其他一些工作:
https://stackoverflow.com/a/1186309/2248340 https://stackoverflow.com/a/105074/2248340
工作原理:
如果按提交,表单数据将被放置在一个对象中。在此对象中也是选定的文件列表。
此对象将在上传帧中推送数组请求。
这里运行看门狗并查看是否有新请求(status = 0) 如果它找到一个新的上传开始。
这是我尝试的测试项目:
框架集:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<frameset rows="*,100">
<frame id="start" name="start" src="start.html">
<frame id="upload" name="upload" src="frame.html">
</frameset>
<noframes>
<body>
<a href="start.html">please use this</a>
</body>
</noframes>
</html>
的start.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Start</title>
<script src="../js/jquery-1.11.3.min.js" ></script>
<script>
var files;
$.fn.serializeObject = function()
{
var o = {};
var a = this.serializeArray();
$.each(a, function() {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
var UploadRequest=function(f)
{
var o= {};
o['guid']=guid();
o['action']=$('form').attr('action');
o['files']=files;
o['values']=$('form').serializeObject();
o['status']=0;
return o;
}
function fileSelect( e){
files=e.target.files;
return false;
}
</script>
</head>
<body>
<form id="test" action="phpinfo.php">
<input name="test" >
<input type="hidden" name="h1" value="2">
<input type="file" name="uploadfile" onchange="fileSelect(event)">
<input type="submit" value="upload‚" >
</form>
<script>
var olddogcounter=localStorage['uploadwatchdog'];
var check=false;
function guid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
}
$(function() {
$('#test').submit(function() {
var request=new UploadRequest();
parent.upload.requests.push(request);
return false;
});
});
</script>
<a href="test.html" >test</a>
</body>
</html>
和上传框架:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>frame</title>
</head>
<body>
<h1>frame</h1>
<iframe id="response" width="100%" height="200"></iframe>
<script>
var requests=new Array();
var counter=0;
function watchdog()
{
for(var i=0; i<requests.length; i++)
{
var request=requests[i];
if(request.status==0)
{
alert("watchdog :"+dump(request));
request.status=1;
uploadFile(request);
}
}
}
function uploadFile(request)
{
var url = request.action;
var xhr = new XMLHttpRequest();
var fd = new FormData();
xhr.open("POST", url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
iframe=document.getElementById("response");
iframe.src="data:text/html;charset=utf-8," + escape(xhr.responseText);
}
};
if(request.files.length>1)
{
for(var i=0; i<request.files.length;i++)
{
var file=request.files[i];
fd.append("upload_file[]", file);
}
}
else
{
var file=request.files[0];
fd.append("upload_file",file );
}
for( var key in request.values)
{
fd.append(key,request.values[key] );
}
xhr.send(fd);
}
window.setInterval(watchdog,2000);
</script>
</body>
</html>
解决方案尚未完成,但我认为这是一个很好的起点。
TODO: - 在列表中显示上载的名称 - 上传后从数组请求中删除请求 - 显示上传的progess栏 - 一些错误处理