天天看點

表單送出enctype參數詳解之:application/x-www-form-urlencode和multipart/form-data

application/x-www-form-urlencode

我們在送出表單的時候,form表單參數中會有一個enctype的參數。enctype指定了HTTP請求的Content-Type。

預設情況下,HTML的form表單的enctype=application/x-www-form-urlencoded。

application/x-www-form-urlencoded是指表單的送出,并且将送出的資料進行urlencode。預設情況下,我們所有的表單送出都是通過這種預設的方式實作的。

在火狐浏覽器下,我們可以看一下送出資料的過程:

表單送出enctype參數詳解之:application/x-www-form-urlencode和multipart/form-data

我們可以看到Content-type:

Content-Type      
application/x-www-form-urlencoded; charset=UTF-8  
           

然後繼續看一下原始請求資料,原始的請求資料被urlencode了。

表單送出enctype參數詳解之:application/x-www-form-urlencode和multipart/form-data

Ajax預設也是通過HTTP application/x-www-form-urlencoded送出資料。可以看下Jquery的源碼:

表單送出enctype參數詳解之:application/x-www-form-urlencode和multipart/form-data

multipart/form-data

一般情況下,我們如果要在表單中上傳檔案,一般會将form的enctype參數設定為multipart/form-data。這種方式隻支援POST的請求方式。

Contype-Type=multipart/form-data情況的時候,都會通過一個特殊的字元串來将原始POST資料進行分割。

我們可以看到下面的請求中Content-type的類型:

Content-Type      
multipart/form-data; boundary=---------------------------66841812532223  
           

其中boundary=---------------------------66841812532223,為分割符号。

其中資料塊開始的分隔符 =={boundary} 會在前面加上“==”

資料塊結束的分隔符 =={boundary}== 會在後面加上“==”

表單送出enctype參數詳解之:application/x-www-form-urlencode和multipart/form-data

繼續看下原始資料,我們可以清晰的看到,各種請求資料被boundary值進行了分割。

表單送出enctype參數詳解之:application/x-www-form-urlencode和multipart/form-data

雖然這些知識點很早就知道了,但是知其然知其是以然可以讓我們深入每一個技術細節。

application/json

有些時候,我們會直接送出Content-type是json資料格式的請求。

例如:

var data = {'title':'test', 'sub' : [1,2,3]};  
$http.post(url, data).success(function(result) {  
    ...  
});  
           

請求:

POST http://www.example.com HTTP/1.1  
Content-Type: application/json;charset=utf-8  

{"title":"test","sub":[1,2,3]}  
           

這種情況下,請求的Content-Type是Json的資料格式,http body中的内容就是請求的json資料。

如果是php的話,需要通過 php://input來接收POST中的原始資料資訊。

如果是Java,則需要下面的方式來讀取HTTP 請求BODY中的資料

protected void processRequest(HttpServletRequest request,HttpServletResponse response) {
    try {
        request.setCharacterEncoding("UTF-8");
        int size = request.getContentLength();  
        System.out.println(size);  
        InputStream is = request.getInputStream();  
        byte[] reqBodyBytes = readBytes(is, size);  
        String res = new String(reqBodyBytes);  
        System.out.println(res);  
        response.setContentType("text/html;charset=UTF-8");  
        response.setCharacterEncoding("UTF-8");  
        response.getOutputStream().write(res.getBytes("utf-8"));  
        response.flushBuffer();  
    } catch (Exception e) {
    }
}

public static final byte[] readBytes(InputStream is, int contentLen) {
    if (contentLen > 0) {
        int readLen = 0;  
        int readLengthThisTime = 0;  
        byte[] message = new byte[contentLen];  
        try {
             while (readLen != contentLen) {
             readLengthThisTime = is.read(message, readLen, contentLen - readLen);
             if (readLengthThisTime == -1) {// Should not happen.  
                 break;
             }
             readLen += readLengthThisTime;
             }
             return message;
        } catch (IOException e) {
            // Ignore  
            // e.printStackTrace();  
        }  
    }
    return new byte[] {};  
}  
           

繼續閱讀