非Ajax实现无刷新页面文件上传

文件上传很常见,也有好些方法,不过我见过的大多是基于flash的,也有用XMLhttpResponse来提交文件的,其实大可不必这么麻烦,我这里介绍一种更具兼容性的用法,利用iframe来曲线实现无刷新页面文件上传功能,这种方法其实也很常见了。

  iframe上传文件原理是这样的:首先input file控件本身是被表单包含的,表单属性必须设置为enctype="multipart/form-data",才能上传任意文件。但是仅仅有这个还不行, 因为提交表单后,它会自动刷新页面,为了不让它离开本页,我们可以在这个提交的页面上动态生成一个隐藏的iframe,但是别忘了在表单上再添加一个属性target,并且指定为iframe的name,这样表单提交后,服务器才会将返回的结果会写在iframe里。最后在从这个iframe里获取数据就可以了。

  原理上不难理解,也不难实现。在这上面还可以扩展出更多的功能,比如上传前判断文件类型,大小之类的,添加一个加载的过程等等。不过在实现的过程,还是遇到了几个难点:一个是获取文件信息,这个在不同的浏览器上,获取的方法不尽相同;另外一个是获取iframe里的内容。这些问题的解决方法,我没有很好的解决,不过貌似也没有什么大问题,所以我把解决的方法写在这里。

获取文件信息:我这里只是实现了获取文件名称的功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
1getFile:  function () {
2 var fileInfo = {};
3 var isIE = !!window.ActiveXObject;
4 //var isIE6 = isIE&&!window.XMLHttpRequest;
5 //var isIE8 = isIE&&!!document.documentMode;
6 //var isIE7 = isIE&&!isIE6&&!isIE8;
7 var path =  '' ;
8if(isIE) {
9path = document.getElementById( this .config.id).value;
10fileInfo.fileName = path.slice(path.lastIndexOf( '\\' )+ 1 );
11 } elsefileInfo.fileName = document.getElementById( this .config.id).files[ 0 ].name;
12returnfileInfo;
13 }

 

获取iframe的内容:

1
document.getElementById( "iframe" ).find( 'body' ).html();

 

  我这里先展示一个基本的上传代码,供各位参考。 我这个是不带界面的,纯逻辑部分。页面须有个<input type='file' id='uploader' name='file'/>标签,然后可以这样调用: 

1
2
3
4
5
6
var uploader = newFileUploader({
action:  'url' //上传地址
onChange:  function () {},  //上传前
loading:  function () {},  //上传过程中
onComplete:  function () {}  //上传完成后
}) ;

 

点击按钮选择一个文件后就会立即提交。 

 完整代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
1functionFileUploader(config) {
2this.config = config;
3this.input = $( '#' + this .config.id);
4this.action =  this .config.action ||  '' ;
5this.method =  this .config.method ||  'post' ;
6this.type =  this .config.type ||  'json' ;
7this.init();
8 }
9FileUploader.prototype = {
10init:  function () {
11 var that =  this ;
12this.addListener( 'change' function () {
13if(that.config.onChange) {
14 var res =  false ;
15res = that.config.onChange.call( this , that.getFile());
16if(!res) returnfalse;
17 }
18that.load();
19 });
20 },
21load:  function () {
22 var that =  this ;
23this.wrap();
24this.send();
25if(that.config.loading) that.config.loading.call(that);
26 $( 'iframe' ).bind( 'load' function () {
27 var data = that.getResponse(document.getElementById( "hidden_frame" )).find( 'body' ).html();
28data = data.replace(/<pre.*>(.*)<\/pre>/,  "$1" );
29if(that.config.onComplete) {
30if(that.type ==  'json' ) data = eval( '(' +data+ ')' );
31that.config.onComplete.call( this , data, that.input);
32 }
33 //this.input.unwrap();
34 $( this ).remove();
35 });
36 },
37getResponse:  function (iframe) {
38 var doc = $(iframe).contents();
39returndoc;
40 },
41remove:  function () {
42this.input.remove();
43 },
44getFile:  function () {
45 var fileInfo = {};
46 var isIE = !!window.ActiveXObject;
47 var isIE6 = isIE&&!window.XMLHttpRequest;
48 var isIE8 = isIE&&!!document.documentMode;
49 var isIE7 = isIE&&!isIE6&&!isIE8;
50 var path =  '' ;
51if(isIE) {
52path = document.getElementById( this .config.id).value;
53fileInfo.fileName = path.slice(path.lastIndexOf( '\\' )+ 1 );
54 } elsefileInfo.fileName = document.getElementById( this .config.id).files[ 0 ].name;
55returnfileInfo;
56 },
57send:  function (cb) {
58 var that =  this ;
59this.input.parent( 'form' ).submit();
60 },
61wrap:  function () {
62this.input.wrap(
63 '<form enctype="multipart/form-data"' +
64 'action="' + this .action+ '" method="' + this .method+ '" target="hidden_frame">' +
65 '</form>'
66 );
67this.input.parent( 'form' ).after(
68 '<iframe name="hidden_frame" id="hidden_frame" src="javascript:false;" ></iframe>'
69 );
70 },
71addListener:  function (type, cb) {
72if(type ==  'change' this .input.bind( 'change' , cb);
73 }
74 };

原文地址:站长部落http://www.zzblo.com/study/javascript/252_2.html

转载于:https://www.cnblogs.com/mblx/archive/2012/04/11/2442591.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值