资讯专栏INFORMATION COLUMN

Javascript无刷新文件上传

longmon / 2971人阅读

摘要:最近工作中遇到上传文件问题,主要需求是一步点击上传,兼容,当时用的控件,这两天扒了一下源码,明白了原理拿出来分享一下。组织页面刷新端代码使用模块将文件暂存在目录下。然后绑定的事件,通过取得中的数据。转自无刷新文件上传

最近工作中遇到上传文件问题,主要需求是一步点击上传,兼容ie8+,当时用的dojox/form/uploader控件,这两天扒了一下源码,明白了原理拿出来分享一下。
总体思路如下:

对于支持XMLHttpRequest2的浏览器使用FormData通过ajax上传

对于ie10一下的浏览器使用iframe异步上传,还需后台服务器做相应处理,这部分也是dojo/request/iframe上传文件的原理。

一、使用FormData上传文件

FormData最频繁使用的功能就是表单序列化及创建与表单格式相同的数据。append方法接收两个参数,字段名与字段值,字段值可以是File、Blob、String.

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。



  
    
    
    FormData
  
  
      

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自动为我们设置请求头部。

兼容性问题

二、使用iframe上传文件

兼容旧版本的ie浏览器实现无刷新上传,只能借由iframe来实现,大多数类库的做法是动态插入一个iframe元素,将form元素的target属性设置为新添加的iframe,这样只刷新了iframe的内容而避免页面跳转到form元素的action属性所指定的url。这里我们根据dojo/request/iframe模块的原理来实现上传文件。
该模块需要后台返回响应的格式来配合。将需要返回的信息放在textarea标签内。然后绑定iframe的load事件,通过doc.getElementsByTagName("textarea")取得textarea中的数据。


  
    
  

下面是简单的demo



    
        
        
    
        ArcGIS Web Application
    
    
        
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 = ""; 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”错误。

  



    
    
    
    
        ArcGIS Web Application
    
    
       

转自:Javascript无刷新文件上传

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/85573.html

相关文章

  • PHP_Ajax

    摘要:简介业务做一个在线投票,给歌手投票。提交到当前页面的中达到效果。用户名密码注册总结在不使用对象的情况下,依然可以用来实现对后台服务器的请求,同时不带来页面刷新或者跳转。 ajax 简介 业务:做一个在线投票,给歌手投票。要求:无刷新,并且不允许使用XMLHttpRequest对象.分析:在XHR对象,没有流行之前,已经有了无刷新这种效果的方法. 从http角度看,可以利用204 No...

    MiracleWong 评论0 收藏0
  • web端文件上传功能的思考

    摘要:概述文件上传是一个很常见的需求,实现文件上传的技术也很多。帮助文档模拟无刷新的文件上传功能页面无刷新上传文件模拟,超简单为什么上传文件的表单里要加个属性接口对象的介绍使用对象涉及文章侵权,请邮件告知。 概述 文件上传是一个很常见的需求,实现文件上传的技术也很多。下面就谈谈一些常见的上传技术以及它们的优劣。 传统表单上传 传统表单文件上传估计是运用最广泛和最简单的技术了,说它简单是...

    Jaden 评论0 收藏0
  • 使用FormData+jQuery+AJAX发送文件至又拍云,实现刷新上传

    摘要:我是一个很菜的人,为了实现无刷新上传图片至又拍云,初学了,如果代码有不好的地方请指出功能通过新功能无刷新上传文件至又拍云七牛云类似附上代码如果不懂得地方就提出来吧下面代码用于生成和用于后面的表单上传你的表单表单去又拍云官网获得你的空间名空间 我是一个很菜的人,为了实现无刷新上传图片至又拍云,初学了jQuery,如果代码有不好的地方请指出 功能:通过HTML5新功能FormData无刷新...

    robin 评论0 收藏0
  • Jquery+AJAX上传文件刷新上传并重命名文件

    摘要:前端提交提交成功格式不对不允许上传这种格式文件已存在文件已存在上传错误上传错误服务器错误上传文件上传服务端获取原始文件名获取文件后缀名设置新文件名允许上传的图片后缀小于上传错误此处可以输出文件的详细信息文件已存在格式不对文件目录记 showImg(https://segmentfault.com/img/bVbwr3B?w=340&h=133); 前端 index.html ...

    only_do 评论0 收藏0
  • 前端常用插件、工具类库汇总

    摘要:页面调试腾讯开发维护的代码调试发布,错误监控上报,用户问题定位。同样是由腾讯开发维护的代码调试工具,是针对移动端的调试工具。前端业务代码工具库。动画库动画库,也是目前通用的动画库。 本人微信公众号:前端修炼之路,欢迎关注 本篇文章整理自己使用过的和看到过的一些插件和工具,方便日后自己查找和使用。 另外,感谢白小明,文中很多的工具来源于此。 弹出框 layer:http://layer....

    GitCafe 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<