HTML上傳文件的多種方式

1. 傳統(tǒng)方式

<form id="upload-form" action="upload.php" method="post" enctype="multipart/form-data" >
   <input type="file" id="upload" name="upload" /> <br />
   <input type="submit" value="Upload" />
</form>
基本上傳控件

2. iframe上傳

用戶點(diǎn)擊submit的時(shí)候,動(dòng)態(tài)插入一個(gè)iframe

var form = $("#upload-form");
form.on('submit',function() {
  // 此處動(dòng)態(tài)插入iframe元素
});

動(dòng)態(tài)插入iframe代碼

var seed = Math.floor(Math.random() * 1000);
var id = "uploader-frame-" + seed;
var callback = "uploader-cb-" + seed;

var iframe = $('<iframe id="'+id+'" name="'+id+'" style="display:none;">');
var url = form.attr('action');
form.attr('target', id).append(iframe).attr('action', url + '?iframe=' + callback);

最后一行垫挨,它為表單添加target屬性韩肝。指向動(dòng)態(tài)插入的iframe。這樣上傳結(jié)束后服務(wù)器將結(jié)果返回iframe窗口九榔。所以當(dāng)前頁面不會(huì)跳轉(zhuǎn)哀峻。其次,在它的action屬性指定的上傳網(wǎng)址的后面添加一個(gè)參數(shù)哲泊,使得服務(wù)器知道回調(diào)函數(shù)的名稱剩蟀。這樣就能將服務(wù)器返回的信息,從iframe窗口傳到上層頁面切威。
服務(wù)器返回的信息應(yīng)該如下:

<script type="text/javascript">
  window.top.window['callback'](data);
</script>

小筆記

if (window.top!=window.self)  //判斷是否是頂層窗口

然后在當(dāng)前網(wǎng)頁中定義回調(diào)函數(shù)

window[callback] = function(data){
  console.log('received callback:', data);
  iframe.remove(); //removing iframe
  form.removeAttr('target');
  form.attr('action', url);
  window[callback] = undefined; //removing callback
};

3. 初步使用FormData(ajax上傳)

ajax上傳文件育特,放在表單的submit事件的回調(diào)函數(shù)中。

form.on('submit',function() {
  // 此處進(jìn)行ajax上傳
});

進(jìn)行ajax上傳

// 檢查是否支持FormData
if(window.FormData) { 
  var formData = new FormData();

  // 建立一個(gè)upload表單項(xiàng)先朦,值為上傳的文件
  formData.append('upload', document.getElementById('upload').files[0]);
  var xhr = new XMLHttpRequest();
  xhr.open('POST', $(this).attr('action'));
  // 定義上傳完成后的回調(diào)函數(shù)
  xhr.onload = function () {
    if (xhr.status === 200) {
      console.log('上傳成功');
    } else {
      console.log('出錯(cuò)了');
    }
  };
  xhr.send(formData);
}

為ajax上傳文件添加進(jìn)度條

  1. 預(yù)先在html中添加progress元素
<progress id="uploadprogress" min="0" max="100" value="0">0</progress>
  1. 定義progress的回調(diào)函數(shù)
xhr.upload.onprogress = function (event) {
  if (event.lengthComputable) {
    var complete = (event.loaded / event.total * 100 | 0);
    var progress = document.getElementById('uploadprogress');
    progress.value = progress.innerHTML = complete;
  }
};

4. 圖片預(yù)覽

// 檢查是否支持FileReader對(duì)象
if (typeof FileReader != 'undefined') {
  var acceptedTypes = {
    'image/png': true,
    'image/jpeg': true,
    'image/gif': true
  };
  if (acceptedTypes[document.getElementById('upload').files[0].type] === true) {
    var reader = new FileReader();
    reader.onload = function (event) {
      var image = new Image();
      image.src = event.target.result;
      image.width = 100;
      document.body.appendChild(image);
    };
    reader.readAsDataURL(document.getElementById('upload').files[0]);
  }
}

5. 拖拽上傳

先在頁面中放置一個(gè)容器,用來接收拖放的文件

<div id="holder"></div>

對(duì)它設(shè)置樣式:

#holder {
  border: 10px dashed #ccc;
  width: 300px;
  min-height: 300px;
  margin: 20px auto;
}

#holder.hover {
  border: 10px dashed #0c0;
}

拖放文件的代碼喳魏,主要是定義dragover锋谐、dragenddrop這三個(gè)事件。

// 檢查瀏覽器是否支持拖放上傳截酷。
if('draggable' in document.createElement('span')){
  var holder = document.getElementById('holder');
  holder.ondragover = function () { this.className = 'hover'; return false; };
  holder.ondragend = function () { this.className = ''; return false; };
  holder.ondrop = function (event) {
    event.preventDefault();
    this.className = '';
    var files = event.dataTransfer.files;
    // do something with files
  };
}

6. 在rails中獲取上傳

file_io = params[:upload]
#可以獲取臨時(shí)文件
file_io.tempfile

7. XMLHttpRequest新版本

**首先新建一個(gè)XMLHttpRequest對(duì)象

var xhr = new XMLHttpRequest();

然后想服務(wù)器發(fā)送一個(gè)HTTP請(qǐng)求

xhr.open('GET', 'example.com');
xhr.send();

接著等待服務(wù)器回應(yīng),還需要監(jiān)控XMLHttpRequest對(duì)象狀態(tài)的變化

xhr.onreadystatechange = function() {
  if(xhr.readyState == 4 && xhr.status == 200) {
    alert(xhr.responseText);
  }else{
    alert(xhr.statusText);
  }
}

XMLHttpRequest對(duì)象的主要屬性

  • xhr.readyState:XMLHttpRequest對(duì)象的狀態(tài)迂苛,等于4表示數(shù)據(jù)已經(jīng)接收完畢就漾。
  • xhr.status:服務(wù)器返回的狀態(tài)碼抑堡,等于200表示一切正常朗徊。
  • xhr.responseText:服務(wù)器返回的文本數(shù)據(jù)
  • xhr.responseXML:服務(wù)器返回的XML格式的數(shù)據(jù)
  • xhr.statusText:服務(wù)器返回的狀態(tài)文本首妖。

新版本XMLHttpRequest的新功能

  • 可以設(shè)置HTTP請(qǐng)求的時(shí)限。
  • 可以使用FormData對(duì)象管理表單數(shù)據(jù)。
  • 可以上傳文件。
  • 可以請(qǐng)求不同域名下的數(shù)據(jù)(跨域請(qǐng)求)棚壁。
  • 可以獲取服務(wù)器端的二進(jìn)制數(shù)據(jù)杯矩。
  • 可以獲得數(shù)據(jù)傳輸?shù)倪M(jìn)度信息。
  1. 請(qǐng)求時(shí)限設(shè)置
xhr.timeout = 200;

設(shè)置事件

xhr.ontimeout = function(event){
  alert('請(qǐng)求超時(shí)袖外!');
}
  1. formData對(duì)象
    首先新建一個(gè)formData對(duì)象
var formData = new FormData();

為FormData對(duì)象添加表單項(xiàng)

formData.append('username','張三');
formData.append('id', '1234');

傳送FormData對(duì)象

xhr.send(formData);

FormData可以獲取變單項(xiàng)

var form = document.getElementById('myform');
var formData = new FormData(form);
formData.append('secret', '123456'); // 添加一個(gè)表單項(xiàng)
xhr.open('POST', form.action);
xhr.send(formData);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末史隆,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子曼验,更是在濱河造成了極大的恐慌泌射,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蚣驼,死亡現(xiàn)場(chǎng)離奇詭異魄幕,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)颖杏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門纯陨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人留储,你說我怎么就攤上這事翼抠。” “怎么了获讳?”我有些...
    開封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵阴颖,是天一觀的道長。 經(jīng)常有香客問我丐膝,道長量愧,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任帅矗,我火速辦了婚禮偎肃,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘浑此。我一直安慰自己累颂,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開白布凛俱。 她就那樣靜靜地躺著紊馏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蒲犬。 梳的紋絲不亂的頭發(fā)上朱监,一...
    開封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音暖哨,去河邊找鬼赌朋。 笑死凰狞,一個(gè)胖子當(dāng)著我的面吹牛篇裁,可吹牛的內(nèi)容都是我干的沛慢。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼达布,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼团甲!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起黍聂,我...
    開封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤躺苦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后产还,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體匹厘,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年脐区,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了愈诚。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡牛隅,死狀恐怖炕柔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情媒佣,我是刑警寧澤匕累,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站默伍,受9級(jí)特大地震影響欢嘿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜也糊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一炼蹦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧显设,春花似錦框弛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至指攒,卻和暖如春慷妙,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背允悦。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國打工膝擂, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓架馋,卻偏偏與公主長得像狞山,于是被迫代替她去往敵國和親裁良。 傳聞我的和親對(duì)象是個(gè)殘疾皇子阳堕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 本文詳細(xì)介紹了 XMLHttpRequest 相關(guān)知識(shí)嗤形,涉及內(nèi)容: AJAX潦嘶、XMLHTTP获枝、XMLHttpReq...
    semlinker閱讀 13,613評(píng)論 2 18
  • Ajax和XMLHttpRequest 我們通常將Ajax等同于XMLHttpRequest悯森,但細(xì)究起來它們兩個(gè)是...
    changxiaonan閱讀 2,223評(píng)論 0 2
  • 一吧兔、老版本的XMLHttpRequest對(duì)象及用法 首先状植,新建一個(gè)XMLHttpRequest的實(shí)例钓瞭。var xh...
    飛魚_JS閱讀 551評(píng)論 0 0
  • 前端無法像原生APP一樣直接操作本地文件驳遵,否則的話打開個(gè)網(wǎng)頁就能把用戶電腦上的文件偷光了,所以需要通過用戶觸發(fā)山涡,用...
    雷波_viho閱讀 819評(píng)論 0 1
  • 看到標(biāo)題時(shí)佳鳖,有些同學(xué)可能會(huì)想:“我已經(jīng)用xhr成功地發(fā)過很多個(gè)Ajax請(qǐng)求了霍殴,對(duì)它的基本操作已經(jīng)算挺熟練了∠捣裕” 我...
    前端渣渣閱讀 5,754評(píng)論 1 12