Javascrpt无刷新文件上传
var data = new FormData(form);
data.append("name", "woodtree");
data.append(file.name, file);
data.append(name, Blob);
如果直接向FormData的构造函数中传入表单元素,可以将表单元素的数据预先填入。
new FormData(document.forms[0])
FormData的另一个便利之处就是不用明确指定Content-Type头部,xhr对象能够根据FormData实例自动配置适当的头部。下面是一个简单的上传文件demo。
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
<title>FormData</title>
</head>
<body>
<form id="uploader" action="/upload" enctype="multipart/form-data">
<input id="app" type="file" multiple>
<input type="submit" value="Submit">
</form>
<script>
var form = document.getElementById('uploader');
var app = document.getElementById('app');
form.addEventListener('submit', function(evt) {
evt.preventDefault();//组织页面刷新
var data = new FormData();
for (var i = 0, len = app.files.length; i < len; i++) {
//file property: name, size, type, lastModifiedDate
var file = app.files[i];
data.append(file.name, file);
} var xhr = new XMLHttpRequest();
xhr.onload = function() {
alert(JSON.parse(xhr.responseText).success);
};
xhr.onerror = function(err) {
console.error(err);
};
xhr.open('post', './upload', true);
xhr.send(data);
}, false);
</script>
</body>
</html>
server端代码使用formidable模块将文件暂存在tmp目录下。
var http = require('http');
var url = require('url');
var fs = require('fs');
var qs = require('querystring');
var request = require('request');
var formidable = require('formidable');
http.createServer(function(req, res){
var _url = url.parse(req.url);
if (_url.pathname === '/index') {
fs.readFile('./index.html', function(err, data) {
res.writeHead(200, {"Content-Type": "text/html; charset=UTF-8"});
res.write(data);
res.end();
});
} else if (_url.pathname === '/upload') {
console.log(req.headers['content-type']);
handle(req, res);
}
}).listen(8888);
var handle = function(req, res) {
if (req.headers['content-type'].indexOf('multipart/form-data') >= 0) {
var formStream = new formidable.IncomingForm();
formStream.uploadDir = './tmp';
formStream.parse(req, function(err, fields, files) {
res.writeHead(200, {"Content-Type": "application/json"});
if (err) {
res.write('{"success": false}');
} else {
res.write('{"success": true}');
}
res.end();
});
}
}
查看请求,xhr自动为我们设置请求头部。

兼容性问题

<html>
<body>
<textarea>
uploadInfo
</textarea>
</body>
</html>
下面是简单的demo
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<meta http-equiv="X-UA-Compatible" content="IE=EDGE" />
<title>ArcGIS Web Application</title>
</head>
<body class="claro">
<form id="uploader" method="post" action="/upload" target="appFrame" encoding="multipart/form-data" enctype="multipart/form-data">
<input id="appInput" name="app" type="file" >
</form>
<iframe id="frame" name="appFrame" src="" style="visibility:hidden;"></iframe>
<script type="text/javascript">
var upload = document.getElementById('placeholder');
var uploader = document.getElementById('uploader');
var app = document.getElementsByName('app')[0];
var clickLietener = function() {
app.click();
}
var changeListener = function() {
uploader.submit();
}
if (app.addEventListener) {
app.addEventListener('change', changeListener, false);
} else if (app.attachEvent) {
app.attachEvent('onchange', changeListener);
}
var appFrame = document.getElementById('frame');
var listener = function() {
var doc = appFrame.contentWindow.document;
var textAreas = doc.getElementsByTagName('textarea');
if (textAreas && textAreas.length > 0) {
var response = textAreas[0].value;
alert(response);
}
}
if (appFrame.addEventListener) {
appFrame.addEventListener('load', function(evt) {
listener();
}, false);
} else if(appFrame.attachEvent) {
appFrame.attachEvent('onload', function() {
listener();
});
} </script>
</body>
</html>
var http = require('http');
var url = require('url');
var fs = require('fs');
var qs = require('querystring');
var formidable = require('formidable');
http.createServer(function(req, res) {
var _url = url.parse(req.url);
if (_url.pathname === '/index') {
fs.readFile('./index.html', function(err, data) {
res.writeHead(200, {
"Content-Type": "text/html; charset=UTF-8"
});
res.write(data);
res.end();
});
} else if (_url.pathname === '/upload') {
var formStream = new formidable.IncomingForm();
formStream.uploadDir = './tmp';
formStream.parse(req, function(err, fields, files) {
console.log(fields);
console.log(files);
var info = null;
var accept = req.headers.accept;
if (err) {
info = {success: false};
} else {
info = {success: true};
}
if (accept.indexOf('application/json') > -1) {
res.writeHead(200, {
"Content-Type": "application/json;charset=utf-8"
});
res.write(JSON.stringify(info));
} else {
res.writeHead(200, {
"Content-Type": "text/html; charset=UTF-8"
});
var responseText = '<html><body><textarea>' +
JSON.stringify(info) +
'</textarea></body></html>';
res.write(responseText);
}
res.end();
});
}
}).listen(8888);
后台代码需要注意Content-Type响应头的设置,ie8、9碰到不知如何渲染的MIME类型会把它当成文件下载下来。这里和这里



不知大家有没有注意到,上面的demo是一步上传,选择好文件后直接上传到服务器,ie8以上的浏览器没问题,如果是在ie8中情况就有些棘手。ie中文件上传控件长成这个样子,单击一下button会弹出文件选择框,如果单击的是text部分,没有反映,你需要双击才会弹出选择框。一个办法是让鼠标尽量单击button部分,button的大小跟font-size有关。但如果你的可点击区域太大。。。。。
所幸还是有解决办法的,这时需要在form中加一个label标签,for属性指向file。这样点击label时会触发for指向元素的click事件,这时label的自然行为。同时把file移除屏幕外。注意一定不能用input[type=button],在点击button时候调用file的click事件,然后在file change事件中调用form.submit方法,这种行为在ie中是被禁止的,回报“access denied”错误。

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<meta http-equiv="X-UA-Compatible" content="IE=EDGE" />
<title>ArcGIS Web Application</title>
</head>
<body class="claro">
<form id="uploader" method="post" action="/upload" target="appFrame" encoding="multipart/form-data" enctype="multipart/form-data">
<label id="placeholder" for="appInput">upload</label>
<input id="appInput" name="app" type="file" style="position:absolute;left:-800px;">
</form>
<iframe id="frame" name="appFrame" src="" style="visibility:hidden;"></iframe>
<script type="text/javascript">
var upload = document.getElementById('placeholder');
var uploader = document.getElementById('uploader');
var app = document.getElementsByName('app')[0];
var changeListener = function() {
uploader.submit();
}
if (app.addEventListener) {
app.addEventListener('change', changeListener, false);
} else if (app.attachEvent) {
app.attachEvent('onchange', changeListener);
}
var appFrame = document.getElementById('frame');
var listener = function() {
var doc = appFrame.contentWindow.document;
var textAreas = doc.getElementsByTagName('textarea');
if (textAreas && textAreas.length > 0) {
var response = textAreas[0].value;
alert(response);
}
}
if (appFrame.addEventListener) {
appFrame.addEventListener('load', function(evt) {
listener();
}, false);
} else if(appFrame.attachEvent) {
appFrame.attachEvent('onload', function() {
listener();
});
} </script>
</body>
</html>
参考资料
Javascrpt无刷新文件上传的更多相关文章
- Asp.Net实现无刷新文件上传并显示进度条(非服务器控件实现)(转)
Asp.Net实现无刷新文件上传并显示进度条(非服务器控件实现) 相信通过Asp.Net的服务器控件上传文件在简单不过了,通过AjaxToolkit控件实现上传进度也不是什么难事,为什么还要自己辛辛苦 ...
- 使用PHP和HTML5 FormData实现无刷新文件上传教程
无刷新文件上传是一个常见而又有点复杂的问题,常见的解决方案是构造 iframe 方式实现. 在 HTML5 中提供了一个 FormData 对象 API,通过 FormData 可以方便地构造一个表单 ...
- 【JS】ajax 实现无刷新文件上传
一.摘要 最近在做个东西,需要实现页面无刷新文件上传,目前看到的方法有两种 1) 通过隐藏iframe 实现页面无刷新,适用于不关心上传结果 <form target="hiddenF ...
- 实用ExtJS教程100例-009:ExtJS Form无刷新文件上传
文件上传在Web程序开发中必不可少,ExtJS Form中有一个filefield字段,用来选择文件并上传.今天我们来演示一下如何通过filefield实现ExtJS Form无刷新的文件上传. 首先 ...
- Asp.Net 无刷新文件上传并显示进度条的实现方法及思路
相信通过Asp.Net的服务器控件上传文件在简单不过了,通过AjaxToolkit控件实现上传进度也不是什么难事,为什么还要自己辛辛苦苦来 实现呢?我并不否认”拿来主义“,只是我个人更喜欢凡是求个所以 ...
- ie8实现无刷新文件上传
ie8由于无法使用FormData,想要无刷新上传文件就显得比较麻烦.这里推荐使用jQuery-File-Upload插件,它能够很方便的解决ie8无刷新文件上传问题.(最低兼容到ie6) jQuer ...
- SpringMVC ajax技术无刷新文件上传下载删除示例
参考 Spring MVC中上传文件实例 SpringMVC结合ajaxfileupload.js实现ajax无刷新文件上传 Spring MVC 文件上传下载 (FileOperateUtil.ja ...
- jquery无刷新文件上传 解决IE安全性问题
很多项目中都需要有文件上传的功能,一般文件上传有几种方式,input file表单上传,flash上传. flash就不说了,能接受flash的就用吧. 下面介绍的这种是基于input file控件的 ...
- php利用iframe实现无刷新文件上传功能
上传原理很简单就是利用表单的打开方式为iframe的name名,这样就可以在当前页面的iframe打来了,实现文件上传,再利用js返回上传结果. form target .在 action 属性中规定 ...
随机推荐
- 学习Java,还需要学好哪些知识
很多人认为学好一门程序语言就需要学好逻辑,其实这对于很多人而言是对的,但是真的对于需要写程序的学员来说,只有逻辑好其实是不够的,如果你能具备以下几项能够为你在程序编译中大大提高工作效率.现在昆明jav ...
- html 页面内锚点定位及跳转方法总结
第一种方法,也是最简单的方法是锚点用<a>标签,在href属性中写入DIV的id.如下: <!DOCTYPE html><html><head> < ...
- bootstrap中table的colspan不起作用
bootstrap中table的colspan不起作用,即在不指定宽度的条件下,各个td宽度不符合colspan指定的宽度. 添加table0layout:fixed后显示正常. table{ tab ...
- Nginx开启Gzip压缩
.Vim打开Nginx配置文件 vim /usr/local/nginx/conf/nginx.conf .找到如下一段,进行修改 gzip on; gzip_min_length 1k; gzip_ ...
- SQL 2008无法连接的解决办法
问题: 在从本地客户端连接到SQL 2008的时候出现无法连接的错误.错误信息如下所示:
- 黑马程序员-scanf函数
变量的内存:字节和地址:1.变量的存储单位是字节,每个字节都有存储地址.2.不同的数据大小占用的内存带下不同拥有的字节数也是不同的.变量的存储:1.存储是按照,先存储的放在地址教高的位置,优先存储的地 ...
- 写好Hive 程序的若干优化技巧和实际案例
使用Hive可以高效而又快速地编写复杂的MapReduce查询逻辑.但是一个”好”的Hive程序需要对Hive运行机制有深入的了解,像理解mapreduce作业一样理解Hive QL才能写出正确.高效 ...
- :尝试加载 Oracle 客户端库时引发 BadImageFormatException。如果在安装 32 位 Oracle 客户端组件的情况下以 64 位模式运行,将出现此问题。 ---> System.BadImageFormatException: 试图加载格式不正确的程序。
iis有程序池有一个属性 是否启用32位应用程序默认是true的特别注意windows2008 服务器系统iis默认的是true 这样发布一下也是必须要做的
- windows编程:画线,简单的碰撞检测,简单的帧率锁定
#define WIN32_LEAN_AND_MEAN #include <windows.h> #include <windowsx.h> #include <mmsy ...
- <input type="file"> change事件异常处理办法
问题:最近发现一个奇怪的bug, 那就是在上传图片需要采用input type=file来进行文件选择.由于为了适应美工的UI图,所以是把选择文件的input框隐藏了.然后通过另外一个按钮的点击事件来 ...