form 提交數據編碼梳理


之前對form單提交的操作一直都是迷迷糊糊,知道怎么用,但是隨着ajax2的出現,我們有更多的方式操作form表單提交,但是底層的原理我們要好好的做個梳理。

常見的form提交有post和get這兩種形式,他們對各自的編碼都有不同的理解,post適合大量數據的提交,語義上改變了數據狀態,get是一種獲取獲取數據的一種形式,兩者在編碼上是有不同的實現。

關於編碼的 form 標簽的屬性

  • accept-charset:可以指定form編碼形式
  • enctype: 規定在發送表單數據之前如何對其進行編碼。有三種設置類型
    • 默認為application/x-www-form-urlencoded:發送前編碼所有字符
    • multipart/form-data:不對字符編碼,包含文件上傳控件的表單時,必須使用該值
    • text/plain:空格轉換為 "+" 加號,但不對特殊字符編碼。
  • method:規定用於發送 form-data 的 HTTP 方法。有 post 和 get

method

瀏覽器使用 method 屬性設置的方法將表單中的數據傳送給服務器進行處理。共有兩種方法:POST 方法和 GET 方法。

如果采用 POST 方法,瀏覽器將會按照下面兩步來發送數據。首先,瀏覽器將與 action 屬性中指定的表單處理服務器建立聯系,一旦建立連接之后,瀏覽器就會按分段傳輸的方法將數據發送給服務器。

在服務器端,一旦 POST 樣式的應用程序開始執行時,就應該從一個標志位置讀取參數,而一旦讀到參數,在應用程序能夠使用這些表單值以前,必須對這些參數進行解碼。用戶特定的服務器會明確指定應用程序應該如何接受這些參數。

另一種情況是采用 GET 方法,這時瀏覽器會與表單處理服務器建立連接,然后直接在一個傳輸步驟中發送所有的表單數據:瀏覽器會將數據直接附在表單的 action URL 之后。這兩者之間用問號進行分隔。

accept-charset

默認的,無論表單提交的method是post 還是 get,都會默認使用頁面的編碼進行數據的編碼,但是一旦指定了這個參數,那么他就會運用你約定的編碼方式來編碼你的數據。

post提交

這里我們使用編碼為GBK的頁面做提交

<form action="/example/html5/demo_form.asp" method="post">
  name: <input type="text" name="fname" /><br />
  <input type="submit" value="提交" />
</form>

提交后為http的內容為

fname=%BA%C3

如果指定 accept-charset 為 UTF-8

<form action="/example/html5/demo_form.asp" method="post" accept-charset="UTF-8">
  name: <input type="text" name="fname" /><br />
  <input type="submit" value="提交" />
</form>

提交的內容為

fname=%E5%A5%BD

get 提交方式

同樣適用GBK頁面編碼提交數據

<form action="/example/html5/demo_form.asp" method="get">
  name: <input type="text" name="fname" /><br />
  <input type="submit" value="提交" />
</form>

由於是get形式提交,參數會在請求的url上展示

example/html5/demo_form.asp?fname=%E5%A5%BD

如果指定 accept-charset 為 UTF-8

<form action="/example/html5/demo_form.asp" method="get" accept-charset="UTF-8">
  name: <input type="text" name="fname" /><br />
  <input type="submit" value="提交" />
</form>

在提交的url后面的參數編碼變為了

example/html5/demo_form.asp?fname=%E5%A5%BD

當然你可以在普通的文本提交里的form表單屬性里加上 enctype=application/x-www-form-urlencoded ,表示要對所有的表單字段做編碼。

enctype="multipart/form-data"

在用表單做文件提交時,我們必須使用這個屬性標示瀏覽器要對編碼,而且你的提交方式必須post。否則你的那文件

比如我們使用get方法來上傳文件

<form 
  action="/example/html5/demo_form.asp" 
  method="get"
  accept-charset="UTF-8"
  enctype="multipart/form-data">
  name: <input type="text" name="fname" />
	<input type="file" name="pic" />
  	<input type="submit" value="提交" />
</form>

提交后數據由url querystring 傳入:

/example/html5/demo_form.asp?fname=asdf&pic=FullSizeRender.jpg

可以看到數據沒了

當我們使用 POST 方法提交數據后

<form 
  action="/example/html5/demo_form.asp" 
  method="post"
  accept-charset="UTF-8"
  enctype="multipart/form-data">
  name: <input type="text" name="fname" />
	<input type="file" name="pic" />
 	<input type="submit" value="提交" />
</form>

可以看到請求體的內容為

------WebKitFormBoundarypbYSrhCXKEdYIDbR
Content-Disposition: form-data; name="fname"

好
------WebKitFormBoundarypbYSrhCXKEdYIDbR
Content-Disposition: form-data; name="pic"; filename="FullSizeRender.jpg"
Content-Type: image/jpeg


------WebKitFormBoundarypbYSrhCXKEdYIDbR--

HTML5 FormData

進入HTML5 時代我們可以使用 ajax2 + FormData 來上傳二進制流。注意請不要設置 xhr 的 contentType, 因為你使用了 form-data 形式上傳數據,應該又瀏覽器來決定:FormBoundary的內容。

var formData = new FormData();

formData.append("username", "好");
formData.append("accountnum", 123456); // 數字 123456 會被立即轉換成字符串 "123456"

var request = new XMLHttpRequest();
request.open("POST", "http://foo.com/submitform.php");
request.send(formData);

在請求里可以看到

------WebKitFormBoundary0SD0cBR9xNMTPnAf
Content-Disposition: form-data; name="username"

好
------WebKitFormBoundary0SD0cBR9xNMTPnAf
Content-Disposition: form-data; name="accountnum"

123456
------WebKitFormBoundary0SD0cBR9xNMTPnAf--


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM