摘要:最近工作中遇到上傳文件問(wèn)題,主要需求是一步點(diǎn)擊上傳,兼容,當(dāng)時(shí)用的控件,這兩天扒了一下源碼,明白了原理拿出來(lái)分享一下。組織頁(yè)面刷新端代碼使用模塊將文件暫存在目錄下。然后綁定的事件,通過(guò)取得中的數(shù)據(jù)。轉(zhuǎn)自無(wú)刷新文件上傳
最近工作中遇到上傳文件問(wèn)題,主要需求是一步點(diǎn)擊上傳,兼容ie8+,當(dāng)時(shí)用的dojox/form/uploader控件,這兩天扒了一下源碼,明白了原理拿出來(lái)分享一下。
總體思路如下:
對(duì)于支持XMLHttpRequest2的瀏覽器使用FormData通過(guò)ajax上傳
對(duì)于ie10一下的瀏覽器使用iframe異步上傳,還需后臺(tái)服務(wù)器做相應(yīng)處理,這部分也是dojo/request/iframe上傳文件的原理。
一、使用FormData上傳文件FormData最頻繁使用的功能就是表單序列化及創(chuàng)建與表單格式相同的數(shù)據(jù)。append方法接收兩個(gè)參數(shù),字段名與字段值,字段值可以是File、Blob、String.
var data = new FormData(form);
data.append("name", "woodtree");
data.append(file.name, file);
data.append(name, Blob);
如果直接向FormData的構(gòu)造函數(shù)中傳入表單元素,可以將表單元素的數(shù)據(jù)預(yù)先填入。
new FormData(document.forms[0])
FormData的另一個(gè)便利之處就是不用明確指定Content-Type頭部,xhr對(duì)象能夠根據(jù)FormData實(shí)例自動(dòng)配置適當(dāng)?shù)念^部。下面是一個(gè)簡(jiǎn)單的上傳文件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(); }); } }
查看請(qǐng)求,xhr自動(dòng)為我們?cè)O(shè)置請(qǐng)求頭部。
兼容性問(wèn)題
二、使用iframe上傳文件兼容舊版本的ie瀏覽器實(shí)現(xiàn)無(wú)刷新上傳,只能借由iframe來(lái)實(shí)現(xiàn),大多數(shù)類庫(kù)的做法是動(dòng)態(tài)插入一個(gè)iframe元素,將form元素的target屬性設(shè)置為新添加的iframe,這樣只刷新了iframe的內(nèi)容而避免頁(yè)面跳轉(zhuǎn)到form元素的action屬性所指定的url。這里我們根據(jù)dojo/request/iframe模塊的原理來(lái)實(shí)現(xiàn)上傳文件。
該模塊需要后臺(tái)返回響應(yīng)的格式來(lái)配合。將需要返回的信息放在textarea標(biāo)簽內(nèi)。然后綁定iframe的load事件,通過(guò)doc.getElementsByTagName("textarea")取得textarea中的數(shù)據(jù)。
下面是簡(jiǎn)單的demo
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);ArcGIS Web Application
后臺(tái)代碼需要注意Content-Type響應(yīng)頭的設(shè)置,ie8、9碰到不知如何渲染的MIME類型會(huì)把它當(dāng)成文件下載下來(lái)。這里和這里
不知大家有沒有注意到,上面的demo是一步上傳,選擇好文件后直接上傳到服務(wù)器,ie8以上的瀏覽器沒問(wèn)題,如果是在ie8中情況就有些棘手。ie中文件上傳控件長(zhǎng)成這個(gè)樣子,單擊一下button會(huì)彈出文件選擇框,如果單擊的是text部分,沒有反映,你需要雙擊才會(huì)彈出選擇框。一個(gè)辦法是讓鼠標(biāo)盡量單擊button部分,button的大小跟font-size有關(guān)。但如果你的可點(diǎn)擊區(qū)域太大。。。。。
所幸還是有解決辦法的,這時(shí)需要在form中加一個(gè)label標(biāo)簽,for屬性指向file。這樣點(diǎn)擊label時(shí)會(huì)觸發(fā)for指向元素的click事件,這時(shí)label的自然行為。同時(shí)把file移除屏幕外。注意一定不能用input[type=button],在點(diǎn)擊button時(shí)候調(diào)用file的click事件,然后在file change事件中調(diào)用form.submit方法,這種行為在ie中是被禁止的,回報(bào)“access denied”錯(cuò)誤。
ArcGIS Web Application
轉(zhuǎn)自:Javascript無(wú)刷新文件上傳
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/85573.html
摘要:簡(jiǎn)介業(yè)務(wù)做一個(gè)在線投票,給歌手投票。提交到當(dāng)前頁(yè)面的中達(dá)到效果。用戶名密碼注冊(cè)總結(jié)在不使用對(duì)象的情況下,依然可以用來(lái)實(shí)現(xiàn)對(duì)后臺(tái)服務(wù)器的請(qǐng)求,同時(shí)不帶來(lái)頁(yè)面刷新或者跳轉(zhuǎn)。 ajax 簡(jiǎn)介 業(yè)務(wù):做一個(gè)在線投票,給歌手投票。要求:無(wú)刷新,并且不允許使用XMLHttpRequest對(duì)象.分析:在XHR對(duì)象,沒有流行之前,已經(jīng)有了無(wú)刷新這種效果的方法. 從http角度看,可以利用204 No...
摘要:概述文件上傳是一個(gè)很常見的需求,實(shí)現(xiàn)文件上傳的技術(shù)也很多。幫助文檔模擬無(wú)刷新的文件上傳功能頁(yè)面無(wú)刷新上傳文件模擬,超簡(jiǎn)單為什么上傳文件的表單里要加個(gè)屬性接口對(duì)象的介紹使用對(duì)象涉及文章侵權(quán),請(qǐng)郵件告知。 概述 文件上傳是一個(gè)很常見的需求,實(shí)現(xiàn)文件上傳的技術(shù)也很多。下面就談?wù)勔恍┏R姷纳蟼骷夹g(shù)以及它們的優(yōu)劣。 傳統(tǒng)表單上傳 傳統(tǒng)表單文件上傳估計(jì)是運(yùn)用最廣泛和最簡(jiǎn)單的技術(shù)了,說(shuō)它簡(jiǎn)單是...
摘要:我是一個(gè)很菜的人,為了實(shí)現(xiàn)無(wú)刷新上傳圖片至又拍云,初學(xué)了,如果代碼有不好的地方請(qǐng)指出功能通過(guò)新功能無(wú)刷新上傳文件至又拍云七牛云類似附上代碼如果不懂得地方就提出來(lái)吧下面代碼用于生成和用于后面的表單上傳你的表單表單去又拍云官網(wǎng)獲得你的空間名空間 我是一個(gè)很菜的人,為了實(shí)現(xiàn)無(wú)刷新上傳圖片至又拍云,初學(xué)了jQuery,如果代碼有不好的地方請(qǐng)指出 功能:通過(guò)HTML5新功能FormData無(wú)刷新...
摘要:前端提交提交成功格式不對(duì)不允許上傳這種格式文件已存在文件已存在上傳錯(cuò)誤上傳錯(cuò)誤服務(wù)器錯(cuò)誤上傳文件上傳服務(wù)端獲取原始文件名獲取文件后綴名設(shè)置新文件名允許上傳的圖片后綴小于上傳錯(cuò)誤此處可以輸出文件的詳細(xì)信息文件已存在格式不對(duì)文件目錄記 showImg(https://segmentfault.com/img/bVbwr3B?w=340&h=133); 前端 index.html ...
摘要:頁(yè)面調(diào)試騰訊開發(fā)維護(hù)的代碼調(diào)試發(fā)布,錯(cuò)誤監(jiān)控上報(bào),用戶問(wèn)題定位。同樣是由騰訊開發(fā)維護(hù)的代碼調(diào)試工具,是針對(duì)移動(dòng)端的調(diào)試工具。前端業(yè)務(wù)代碼工具庫(kù)。動(dòng)畫庫(kù)動(dòng)畫庫(kù),也是目前通用的動(dòng)畫庫(kù)。 本人微信公眾號(hào):前端修煉之路,歡迎關(guān)注 本篇文章整理自己使用過(guò)的和看到過(guò)的一些插件和工具,方便日后自己查找和使用。 另外,感謝白小明,文中很多的工具來(lái)源于此。 彈出框 layer:http://layer....
閱讀 3609·2021-11-15 11:37
閱讀 2974·2021-11-12 10:36
閱讀 4403·2021-09-22 15:51
閱讀 2381·2021-08-27 16:18
閱讀 882·2019-08-30 15:44
閱讀 2164·2019-08-30 10:58
閱讀 1769·2019-08-29 17:18
閱讀 3269·2019-08-28 18:25