上傳文件的表單中<form>要加屬性enctype="multipart/form-data",不少人只是死記硬背知道上傳表單要這麼 寫,知其然而不知其因此然。那到底爲何要添加這個屬性呢?它是什麼意思呢?它又有什麼其餘可選值呢? 其實form表單在你不寫enctype屬性時,也默認爲其添加了enctype屬性值,默認值是enctype="application/x- www-form-urlencoded".這個屬性管理的是表單的MIME編碼,共有三個值可選:
①application/x-www-form-urlencoded (默認值)
②multipart/form-data
③text/plain
其中①application/x-www-form-urlencoded是默認值,你們可能在AJAX裏見過這 個:xmlHttp.setRequestHeader("Content-Type","application/x-www-form- urlencoded"); 這兩個要作的是同一件事情,就是設置表單傳輸的編碼。在AJAX裏不寫有可能會報錯,可是在HTML的form表單裏是能夠不寫 enctype="application/x-www-form-urlencoded"的,由於默認HTML表單就是這種傳輸編碼類型。而 ②multipart-form-data是用來指定傳輸數據的特殊類型的,主要就是咱們上傳的非文本的內容,好比圖片或者mp3等等。 ③text/plain是純文本傳輸的意思,在發送郵件時要設置這種編碼類型,不然會出現接收時編碼混亂的問題,網絡上常常拿text/plain和 text/html作比較,其實這兩個很好區分,前者用來傳輸純文本文件,後者則是傳遞html代碼的編碼類型,在發送頭文件時才用得上。①和③都不能用 於上傳文件,只有multipart/form-data才能完整的傳遞文件數據。
上面提到的MIME,它的英文全稱是"Multipurpose Internet Mail Extensions" 多功能Internet 郵件擴充服務,它是一種多用途網際郵件擴充協議,在1992年最先應用於電子郵件系統,但後來也應用到瀏覽器。服務器會將它們發送的多媒體數據的類型告訴 瀏覽器,而通知手段就是說明該多媒體數據的MIME類型,從而讓瀏覽器知道接收到的信息哪些是MP3文件,哪些是Shockwave文件等等。服務器將 MIME標誌符放入傳送的數據中來告訴瀏覽器使用哪一種插件讀取相關文件。
簡單說,MIME類型就是設定某種擴展名的文件用一種應用程序來打開的方式類型,當該擴展名文件被訪問的時候,瀏覽器會自動使用指定應用程序來打開。多用於指定一些客戶端自定義的文件名,以及一些媒體文件打開方式。
瀏覽器接收到文件後,會進入插件系統進行查找,查找出哪一種插件能夠識別讀取接收到的文件。若是瀏覽器不清楚調用哪一種插件系統,它可能會告訴用戶缺乏某 插件,或者直接選擇某現有插件來試圖讀取接收到的文件,後者可能會致使系統的崩潰。傳輸的信息中缺乏MIME標識可能致使的狀況很難估計,由於某些計算機 系統可能不會出現什麼故障,但某些計算機可能就會所以而崩潰。
檢查一個服務器是否正確設置了MIME類型的步驟是:
1. 在Netscape瀏覽器中打開服務器網頁
2. 進入"View"菜單,選擇"Page Info"
3. 在彈出的窗口中點擊上層框架中的"EMBED"
4. 在下層框架中查看MIME的類型是否爲"application/x-director"或"application/x-shockwave- flash",若是是上述信息的話代表服務器已經正確設置了MIME類型;而若是MIME類型列出的是文本內容、八位一組的數據或是其它形式均代表服務器 的MIME類型沒有設置正確。
若是服務器沒有正確標明其發送的數據的類型,服務器管理員應該正確添加相關信息,具體操做方法很是簡單快捷。
每一個MIME類型由兩部分組成,前面是數據的大類別,例如聲音audio、圖象image等,後面定義具體的種類。
常見的MIME類型
超文本標記語言文本 .html,.html text/html
普通文本 .txt text/plain
RTF文本 .rtf application/rtf
GIF圖形 .gif image/gif
JPEG圖形 .jpeg,.jpg image/jpeg
au聲音文件 .au audio/basic
MIDI音樂文件 mid,.midi audio/midi,audio/x-midi
RealAudio音樂文件 .ra, .ram audio/x-pn-realaudio
MPEG文件 .mpg,.mpeg video/mpeg
AVI文件 .avi video/x-msvideo
GZIP文件 .gz application/x-gzip
TAR文件 .tar application/x-tar
Internet中有一個專門組織IANA來確認標準的MIME類型,但Internet發展的太快,不少應用程序等不及IANA來確認他們使用 的MIME類型爲標準類型。所以他們使用在類別中以x-開頭的方法標識這個類別尚未成爲標準,例如:x-gzip,x-tar等。事實上這些類型運用的 很普遍,已經成爲了事實標準。只要客戶機和服務器共同認可這個MIME類型,即便它是不標準的類型也沒有關係,客戶程序就能根據MIME類型,採用具體的 處理手段來處理數據。而Web服務器和瀏覽器(包括操做系統)中,缺省都設置了標準的和常見的MIME類型,只有對於不常見的 MIME類型,才須要同時設置服務器和客戶瀏覽器,以進行識別。
----------------------------------------------------------------
表單中enctype="multipart/form-data"的意思,是設置表單的MIME編碼。默認狀況,
這個編碼格式是application/x-www-form-urlencoded,不能用於文件上傳;
只有使用了multipart/form-data,才能完整的傳遞文件數據,進行下面的操做.
enctype="multipart/form-data"是上傳二進制數據; form裏面的input的值以2進制的方式傳過去。
form裏面的input的值以2進制的方式傳過去,
因此request就得不到值了。也就是說加了這段代碼,用request就會傳遞不成功,取表單值加入數據庫時,用到下面的:
SmartUpload su = new SmartUpload();//新建一個SmartUpload對象
su.getRequest().getParameterValues();取數組值
su.getRequest().getParameter( );取單個參數單個值html
一,HTTP上傳的基本知識 ajax
在Form元素的語法中,EncType代表提交數據的格式 用 Enctype 屬性指定將數據回發到服務器時瀏覽器使用的編碼類型。下邊是說明: application/x-www-form-urlencoded: 窗體數據被編碼爲名稱/值對。這是標準的編碼格式。 multipart/form-data: 窗體數據被編碼爲一條消息,頁上的每一個控件對應消息中的一個部分。 text/plain:窗體數據以純文本形式進行編碼,其中不含任何控件或格式字符。
補充
form的enctype屬性爲編碼方式,經常使用有兩種:application/x-www-form-urlencoded和multipart/form-data,默認爲application /x-www-form-urlencoded。數據庫
當action爲get時候,瀏覽器用x-www-form-urlencoded的編碼方式把form數據轉換成一個字串(name1=value1& amp; amp;name2=value2...),而後把這個字串append到url後面,用?分割,加載這個新的url。數組
當action爲post時候,瀏覽器把form數據封裝到http body中,而後發送到server。瀏覽器
若是沒有type=file的控件,用默認的application/x-www-form-urlencoded就能夠了。可是若是有 type=file的話,就要用到multipart/form-data了。瀏覽器會把整個表單以控件爲單位分割,併爲每一個部分加上 Content-Disposition(form-data或者file),Content-Type(默認爲text/plain),name(控件 name)等信息,並加上分割符(boundary)。服務器
二,使用中須要注意的地方網絡
在AJAX往服務器上傳數據是,設置了content-type爲application/x-www-form-urlencoded,此時是對整個發 送內容做了編碼,並非對名字對應的值作了編碼。所以,在服務器端,經過request.getParameter("name")的方式取值,是有問題 的。app
有兩種解法辦法:框架
1)改服務器端: 採用流的方式硬編碼ide
InputStream stream=request.getInputStream();
InputStreamReader isr=new InputStreamReader(stream);
BufferedReader br=new BufferedReader(isr);
String str=br.readLine();
System.out.println(str);
str=URLDecoder.decode(str,"gb2312");
System.out.println(str);
br.close();
2)改客戶端:更改數據發送結構
在往服務器上發數據的時候,使用name=escape(value)的方式組對
此時在服務器代碼中,經過request.getParameter("name")得到的數值,就不用編碼了