詳解前端文件上傳

js實(shí)現(xiàn)文件上傳

四種常見的post數(shù)據(jù)類型

首先文件上傳首先想到的發(fā)post丐重,當(dāng)然還有其他的上傳協(xié)議望抽,我們這里只介紹發(fā)post丑罪。
post支持四種content-type:

  • application/x-www-form-urlencoded

Content-Type 被指定為 application/x-www-form-urlencoded爪模;其次沃琅,提交的數(shù)據(jù)按照 key1=val1&key2=val2 的方式進(jìn)行編碼殴蹄,key 和 val 都進(jìn)行了 URL 轉(zhuǎn)碼究抓。

  • multipart/form-data
Request URL:http://192.168.13.11:8080/fetch2/test/test3
Request Method:POST
Status Code:200 OK
Request Headers:
Accept:*/*
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:6010
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryk0in9FHBncyu30RT
Host:192.168.13.11:8080
Origin:null
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36
Request Payload
------WebKitFormBoundaryk0in9FHBncyu30RT
Content-Disposition: form-data; name="file1"; filename="main.cpp"
Content-Type: application/octet-stream


------WebKitFormBoundaryk0in9FHBncyu30RT--

首先生成了一個(gè) boundary 用于分割不同的字段,為了避免與正文內(nèi)容重復(fù)袭灯,boundary 很長很復(fù)雜刺下。然后 Content-Type 里指明了數(shù)據(jù)是以 mutipart/form-data 來編碼,本次請求的 boundary 是什么內(nèi)容稽荧。消息主體里按照字段個(gè)數(shù)又分為多個(gè)結(jié)構(gòu)類似的部分橘茉,每部分都是以 --boundary 開始,緊接著內(nèi)容描述信息姨丈,然后是回車畅卓,最后是字段具體內(nèi)容(文本或二進(jìn)制)。如果傳輸?shù)氖俏募瘢€要包含文件名和文件類型信息翁潘。消息主體最后以 --boundary-- 標(biāo)示結(jié)束。
RFC1867

  • application/json

application/json這個(gè)Content-Type都比較熟悉筋现,當(dāng)然也可以把json放到formData中唐础;
RFC4657

  • text/xml

參見RFC,也比較常見矾飞。
XML-RFC

實(shí)現(xiàn)文件上傳有2種方式

  1. 普通post請求
    該請求指的是content-type是application/json或text/xml一膨,這種方式很簡單,讀取文件內(nèi)容洒沦,然后上傳即可豹绪,當(dāng)然,有很多局限性申眼;
  2. 利用formdata
    formdata文件上傳是以二進(jìn)制流形式上傳瞒津,且無需寫額外代碼。
  • 創(chuàng)建formdata:
//添加form標(biāo)簽
<form enctype="multipart/form-data" method="post" name="fileinfo" id="myFormElement">
</form>
//創(chuàng)建formdata
var formElement = document.getElementById("myFormElement");
formData = new FormData(formElement);
//若有其他元素不在表單里的括尸,可以通過append添加
formData.append("bookid",$('#bookID'.val()));
  • 使用formData發(fā)送文件

在HTML中要有一個(gè)包含了文件輸入框的form元素巷蚪,表單里元素的name一定要寫,最終形成formData時(shí)濒翻,是以name作為key值

<form enctype="multipart/form-data" method="post" name="fileinfo">
  <label>書名:</label>
  <input type="text" name="bookname" /><br />
  <label>bookid:</label>
  <input type="text" name="bookid"  /><br />
  <label>File to stash:</label>
  <input type="file" name="file" />
</form>
<div id="output"></div>
<a href="javascript:sendForm()">Stash the file!</a>

如果直接在form里寫action的話屁柏,會刷新表單啦膜,同步請求。所以用發(fā)送異步post請求方式淌喻。

function sendForm() {
  var oOutput = document.getElementById("output");
  var oData = new FormData(document.forms.namedItem("fileinfo"));

  //userName不在表單中
  oData.append("userName", "lilei");
  var oReq = new XMLHttpRequest();
  oReq.open("POST", "stash.php", true);
  oReq.onload = function(oEvent) {
    if (oReq.status == 200) {
      oOutput.innerHTML = "Uploaded!";
    } else {
      oOutput.innerHTML = "Error " + oReq.status + " occurred uploading your file.<br \/>";
    }
  };

  oReq.send(oData);
}

你還可以不借助HTML表單,直接向FormData對象中添加一個(gè)File對象或者一個(gè)Blob對象:

data.append("myfile", myBlob);

你還可以使用jQuery來發(fā)送FormData,但必須要正確的設(shè)置相關(guān)選項(xiàng):

var fd = new FormData(document.getElementById("fileinfo"));
//userName不在表單中
  oData.append("userName", "lilei");
$.ajax({
  url: "stash.php",
  type: "POST",
  data: fd,
  processData: false,  // 告訴jQuery不要去處理發(fā)送的數(shù)據(jù)
  contentType: false   // 告訴jQuery不要去設(shè)置Content-Type請求頭
});

MDN:使用FormData

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末僧家,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子裸删,更是在濱河造成了極大的恐慌八拱,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件涯塔,死亡現(xiàn)場離奇詭異肌稻,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)伤塌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進(jìn)店門灯萍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來轧铁,“玉大人每聪,你說我怎么就攤上這事〕莘纾” “怎么了药薯?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長救斑。 經(jīng)常有香客問我童本,道長,這世上最難降的妖魔是什么脸候? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任穷娱,我火速辦了婚禮,結(jié)果婚禮上运沦,老公的妹妹穿的比我還像新娘泵额。我一直安慰自己,他們只是感情好携添,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布嫁盲。 她就那樣靜靜地躺著,像睡著了一般烈掠。 火紅的嫁衣襯著肌膚如雪羞秤。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天左敌,我揣著相機(jī)與錄音瘾蛋,去河邊找鬼。 笑死矫限,一個(gè)胖子當(dāng)著我的面吹牛哺哼,可吹牛的內(nèi)容都是我干的京革。 我是一名探鬼主播,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼幸斥,長吁一口氣:“原來是場噩夢啊……” “哼匹摇!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起甲葬,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤廊勃,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后经窖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體坡垫,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年画侣,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了冰悠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,144評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡配乱,死狀恐怖溉卓,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情搬泥,我是刑警寧澤桑寨,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站忿檩,受9級特大地震影響尉尾,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜燥透,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一沙咏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧班套,春花似錦肢藐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至杉女,卻和暖如春瞻讽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背熏挎。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工速勇, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人坎拐。 一個(gè)月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓烦磁,卻偏偏與公主長得像养匈,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子都伪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評論 2 355

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理呕乎,服務(wù)發(fā)現(xiàn),斷路器陨晶,智...
    卡卡羅2017閱讀 134,672評論 18 139
  • 最近項(xiàng)目需要使用 Angular猬仁,對于初學(xué) Angular 的我只能硬著頭皮上了,項(xiàng)目中有一個(gè)需求是文件上傳先誉,磕磕...
    雖萬萬人吾往矣閱讀 18,278評論 3 20
  • /*----------------- 01 POST上傳單個(gè)文件 -----------------*/ 重點(diǎn):...
    藍(lán)心兒的藍(lán)色之旅閱讀 2,275評論 0 5
  • 整體Retrofit內(nèi)容如下: 1湿刽、Retrofit解析1之前哨站——理解RESTful2、Retrofit解析2...
    隔壁老李頭閱讀 15,085評論 4 39
  • iOS開發(fā)系列--網(wǎng)絡(luò)開發(fā) 概覽 大部分應(yīng)用程序都或多或少會牽扯到網(wǎng)絡(luò)開發(fā)褐耳,例如說新浪微博诈闺、微信等,這些應(yīng)用本身可...
    lichengjin閱讀 3,666評論 2 7