.post与 .ajax,关于post与ajax post的数据类型
form表單提交
傳統的form表單提交只需要一個form標簽,指定action、method='POST',并期望服務器返回一個text/html頁面。
傳統表單post請求頭
請求體
可以看到請求頭中的字段,指明了content-type、content-length,post的內容為application/x-www-form-urlencoded格式的純文本,這個mime類型也是表單的默認編碼屬性(enctype)
再來看看表單post上傳文件的情況。最早的HTTP POST是不支持文件上傳的,給編程開發帶來很多問題。但是在1995年,ietf出臺了rfc1867,也就是《RFC 1867 -Form-based File Upload in HTML》,用以支持文件上傳。所以Content-Type的類型擴充了multipart/form-data用以支持向服務器發送二進制數據。form需要被指定enctype=multipart/form-data
from設置了multipart/form-data后就將以二進制形式傳輸數據了。
包含上傳文件的表單post請求頭
請求體
可以看到請求頭中指定了mime類型與請求體數據分隔符。根據RFC 1867定義,我們需要選擇一段數據作為“分割邊界”( boundary屬性),這個“邊界數據”不能在內容其他地方出現,一般來說使用一段從概率上說“幾乎不可能”的數據即可。
下面的數據便根據boundary劃分段,每一段便是一項數據。(每個field被分成小部分,而且包含一個value是"form-data"的"Content-Disposition"的頭部;一個"name"屬性對應field的ID,等等,文件的話包括一個filename)。
數據內容以兩條橫線結尾,并以一個換行結束。
傳統表單post提交發送兩種格式的數據,application/x-www-form-urlencoded -> 請求體為純文本; multipart/form-data -> 請求體為二進制數據
ajax post
ajax send支持以下幾種數據類型:
void send(ArrayBufferView data);
void send(Blob data);
void send(Document data);
void send(DOMString data);
void send(FormData data);
總體可分為,發送 文本 / 二進制 數據。文本(Document, DOMString),二進制(Blob,ArrayBufferView,FormData)
DOMString
xhr.send(DOMString)類型時,若之前未指定請求頭的Content-Type,則默認發送text/plain類型的數據;而一般服務器期望接收urlencoded或json格式的數據,以解析得到對象。因此在發送前需指定:
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); // 或
xhr.setRequestHeader('Content-Type', 'application/json');
Doucment
Blob、ArrayBufferView
Blob是計算機界通用術語之一,全稱寫作:BLOB (binary large object),表示二進制大對象。
創建Blob對象的方法有幾種,可以調用Blob構造函數,詳情移步 https://developer.mozilla.org/en-US/docs/Web/API/Blob
xhr可以直接send一個Blob對象,請求頭中的Content-Type等于創建Blob時指定的MIME Type
var data = new Blob(['hello world'], {type: 'text/plain'});
xhr.send(data);
關于Blob、ArrayBufferView、File三個類型之間的關系,可以用下圖簡單表述:
關系
ArrayBuffer是一段內存,要操作它必須通過ArrayBufferView(是一個Helper類型,它的具體實現有TypedArray與DataView兩種);
構造Blob接收ArrayBuffer、ArrayBufferView、DOMString、Blob四種類型的數據,以及MIMIE type參數。Blob對象有slice方法可以切割數據,可以append一段ArrayBuffer數據;此外這個類型的最常見用途是在xhr.send()與URL.createObjectURL()。
ArrayBuffer表示二進制數據的原始緩沖區,該緩沖區用于存儲各種類型化數組的數據,是二進制數據通用的固定長度容器。
類型化數組(Typed Arrays)是JavaScript中新出現的一個概念,專為訪問原始的二進制數據而生。
DataView對象在可以在ArrayBuffer中的任何位置讀取和寫入不同類型的二進制數據。
來看兩個例子:
1、直接操作ArrayBuffer 并send ArrayBufferView 來模擬發送表單文本數據
var xhr = new XMLHttpRequest();
xhr.open('POST', '/onpost');
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
var ab = new ArrayBuffer(10);
var tab = new Int8Array(ab);
for (var i=0; i
tab[i] = 97+i;
}
tab[5]=61; // =
xhr.send(tab);
來看看請求報文:
POST http://localhost:10000/onpost HTTP/1.1
Host: localhost:10000
Connection: keep-alive
Content-Length: 10
Origin: http://localhost:10000
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept: */*
Referer: http://localhost:10000/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8
abcde=ghij
2、發送Blob數據
var bb = new Blob(['hello=world'], {type:'application/x-www-form-urlencoded'});
xhr.send(bb);
效果與例子1相同。
當然,實際應用中不會用這種方式來發text。。這里僅是模擬,表明服務器解析報文是根據Content-Type與請求體內容來的。有傳輸其他MIME Type的二進制數據的需求,服務器端需要作相應的處理。NodeJS的常用parser中間件body-parser、multer,分別只能解析application/x-www-form-urlencoded與application/json,multipart/form-data類型。
http://www.jianshu.com/p/83be90945336 這篇文章對于js操作、傳輸二進制數據的講解十分通俗易懂。
File
File顧名思意就是“文件”,通常而言,表示我們使用file控件()選擇的FileList對象,或者是使用拖拽操作搞出的DataTransfer對象。
這里的File對象也是二進制對象,因此,從屬于Blob對象,Blob對象的一些屬性與方法,File對象同樣適合,且推薦使用Blob對象的屬性與方法。
來看一個xhr.send(file)的例子:
var file = $('input[type="file"]').files[0]; // 我上傳了一個jpg
xhr.send(file);
請求頭:
POST http://localhost:10000/onpost HTTP/1.1
Host: localhost:10000
Connection: keep-alive
Content-Length: 178854
Origin: http://localhost:10000
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36
Content-Type: image/jpeg
Accept: */*
Referer: http://localhost:10000/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8
瀏覽器會根據file的MIMIE類型填寫Content-Type,以及Content-Length(字節數)。
FormData
以上傳輸二進制數據 / 文件的方法都不如FormData常用。
XMLHttpRequest Level 2添加了一個新的接口FormData. 利用FormData對象,我們可以通過JavaScript用一些鍵值對來模擬一系列表單控件,我們還可以使用XMLHttpRequest的send()方法來異步的提交這個”表單”。比起普通的ajax, 使用FormData的最大優點就是我們可以異步上傳一個二進制文件。
xhr.send(FormData)時,與傳統表單POST multipart/from-data一樣,指定了請求頭中的Content-Type、Boundary。
總結
以上是生活随笔為你收集整理的.post与 .ajax,关于post与ajax post的数据类型的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: css好用吗,一些不好记却很好用的 CS
- 下一篇: 连续开车8小时!男子长期久坐后被诊断截瘫