1. 程式人生 > >HTML enctype=“multipart/form-data”是什麼?為什麼要加?

HTML enctype=“multipart/form-data”是什麼?為什麼要加?

1.什麼是multipart/form-data
首先我們需要明白在html中的enctype屬性, 
enctype:規定了form表單在傳送到伺服器時候編碼方式。他有如下的三個值。 
①application/x-www-form-urlencoded。預設的編碼方式。但是在用文字的傳輸和MP3等大型檔案的時候,使用這種編碼就顯得 效率低下。 
②multipart/form-data 。 指定傳輸資料為二進位制型別,比如圖片、mp3、檔案。 
③text/plain。純文體的傳輸。空格轉換為 “+” 加號,但不對特殊字元編碼。

2.明確在enctype引數為application/x-www-form-urlencoded的時候post和get請求引數和請求體是什麼形式的
get請求

請求頭: 
GET/www.xxx.com?name=%22hello+world%22&**file=temp.png**&submit=submit HTTP/1.1 

因為get請求沒有請求體,所有他的所有引數都是在url的後邊新增。type=file的表單項只能獲取到檔案的名字,並不能獲取檔案的內容。

post請求 
請求頭:

POST /www.baidu.com HTTP/1.1
1
2
請求體:

name=%22hello+world%22&file=temp.png&submit=submit
1
2
(1)我們可以發現不管是post請求和get請求,他們的引數存在的形式都是不變的,通過key=value的形式存在。 
(2)表單項type=filed只能獲取獲取檔案的名字不能獲取檔案的內容。

2. 明確在enctype引數為multipart/form-data的時候post和get請求引數和請求體是什麼形式的
get請求 
請求頭:

GET/www.xxx.com?name=%22hello+world%22&file=temp.png&submit=submit HTTP/1.1
1
get請求和multipart/form-data結合無效,因為檔案上傳需要請求體。

post請求:

請求頭:

POST /www.xxx.com HTTP/1.1
1
2
請求體:

------WebKitFormBoundaryIZDrYHwuf2VJdpHw
Content-Disposition: form-data; name="name"

"hello world"
------WebKitFormBoundaryIZDrYHwuf2VJdpHw
Content-Disposition: form-data; name="file"; filename="temp.png"
Content-Type: image/png

.PNG
.
...
IHDR...
..........Y../..,+|.$aIk.v...G?...P.P,,...m..e.2....v.7.    pHYs...%...%.IR$....|IDAT(.cTT....................:.?.......}.(.Pd`A..V...L...?..#.....4.o..LS.....W.d.?...A8..LS...(.u.......D.b......b.....o&..;..<.1......IEND.B`.
------WebKitFormBoundaryIZDrYHwuf2VJdpHw
Content-Disposition: form-data; name="submit"

submit
------WebKitFormBoundaryIZDrYHwuf2VJdpHw--
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
通過觀察發現這個的請求體就發生了變化。這種請求體被稱之為多部件請求體。 
什麼是多部件請求體:就是把每一個表單項分割為一個部件。 
因為表單項分為普通表單項和檔案表單項,所以說部件也有區別。 
普通表單項: 
一個請求頭:Content-Disposition: form-data; name=”name” 
一個請求體:裡面就是我們表單的值”hello world”

檔案表單項: 
兩個請求頭:

Content-Disposition: form-data; name="file"; filename="temp.png"
1
Content-Type: image/png
1
2
一個請求體:

.PNG
.
...
IHDR...
..........Y../..,+|.$aIk.v...G?...P.P,,...m..e.2....v.7.    pHYs...%...%.IR$....|IDAT(.cTT....................:.?.......}.(.Pd`A..V...L...?..#.....4.o..LS.....W.d.?...A8..LS...(.u.......D.b......b.....o&..;..<.1......IEND.B`.
------WebKitFormBoundaryIZDrYHwuf2VJdpHw
Content-Disposition: form-data; name="submit"

submit
------WebKitFormBoundaryIZDrYHwuf2VJdpHw--
1
2
3
4
5
6
7
8
9
10
總結:引數獲取不到主要是因為在使用multipart/form-data屬性之後請求體發生了變化。不是key=value的形式出現所以說獲取不到。 
解決辦法: 
(1)我們可以通過js程式碼來些修改,把我們的引數追加在url的後邊。

<form id="upload" name="upload" action="fileftp.jsp" method="post" ENCTYPE="multipart/form-data">
    <input type="hidden" name="otherName" id="otherName" value="abcdefg"/>  
    <td nowrap>
        <input type="file" id="file1" name="file1" value="" size="40" class="sbttn"/>
        <input type="submit" value="上傳" class="sbttn"/>
    </td>   
</form>
1
2
3
4
5
6
7
<script language="javascript">      
function formSubmit(){
    var action="fileftp.jsp";       
    action+="?otherName="+document.upload.otherName.value;
    document.upload.action=action;      
    document.upload.submit();
}
</script>
1
2
3
4
5
6
7
8
(2)通過修改伺服器端程式碼。前提是利用jar包。 
commons-fileupload-1.2.2.jar和commons-io-1.4.jar

//建立工廠
        DiskFileItemFactory factoy=new DiskFileItemFactory();
        //建立解析器
        ServletFileUpload sfu=new ServletFileUpload(factoy);
        //解析request
        try {
            List<FileItem> list=sfu.parseRequest(request);

            for (FileItem fileItem : list) {

                fileItem.getFieldName();
                System.out.println(fileItem.getString());
            }

        } catch (FileUploadException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
上傳圖片示例程式碼:

  <h1>新增圖書</h1>
    <p style="font-weight: 900; color: red">${msg}</p>
    <form action="<c:url value='/UploadServlet'/>" method="post" enctype="multipart/form-data">

        圖書名稱:<input style="width: 150px; height: 20px;" type="text" name="bname"/><br/>
        圖書圖片:<input style="width: 223px; height: 20px;" type="file" name="image"/><br/>
        圖書單價:<input style="width: 150px; height: 20px;" type="text" name="price"/><br/>
        圖書作者:<input style="width: 150px; height: 20px;" type="text" name="author"/><br/>
        圖書分類:<select style="width: 150px; height: 20px;" name="cid">
        <c:forEach items="${list}" var="cate"> 
            <option value="${cate.cid }">${cate.cname }</option>

        </c:forEach>
        </select>
        <br/>
        <input type="submit" value="新增圖書"/>
    </form>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package cn.zll.bookstore.adminbook.servlet;

import java.awt.Image;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.UUID;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.swing.ImageIcon;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import cn.zll.bookstore.adminbook.service.service;
import cn.zll.bookstore.book.domain.Book;

public class UploadServlet extends HttpServlet {


    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        service s=new service();
        response.setContentType("text/html;charset=utf-8");
        request.setCharacterEncoding("utf-8");

        //檔案上傳的三部曲
        //建立工廠
        DiskFileItemFactory factoy=new DiskFileItemFactory();
        //建立解析器
        ServletFileUpload sfu=new ServletFileUpload(factoy);
        //設定上傳檔案的大小
        sfu.setFileSizeMax(20*1024);
        //解析request
        try {
            List<FileItem> list=sfu.parseRequest(request);
            Book b=new Book();
            b.setBid(UUID.randomUUID().toString().replace("-", ""));
            String bname=list.get(0).getString("utf-8");
            b.setBname(bname);
            System.out.println(bname);
            String price=list.get(2).getString("utf-8");
            b.setPrice(price);
            String author=list.get(3).getString("utf-8");
            b.setAuthor(author);
            String cid=list.get(4).getString("utf-8");
            b.setCid(cid);
            System.out.println(bname+price+author+cid);
//          圖書名稱:<input style="width: 150px; height: 20px;" type="text" name="bname"/><br/>
//          圖書圖片:<input style="width: 223px; height: 20px;" type="file" name="image"/><br/>
//          圖書單價:<input style="width: 150px; height: 20px;" type="text" name="price"/><br/>
//          圖書作者:<input style="width: 150px; height: 20px;" type="text" name="author"/><br/>
//          圖書分類:<select style="width: 150px; height: 20px;" name="cid">
//      
//          
            //設定圖片儲存的目錄
            String path=this.getServletContext().getRealPath("/book_img");
            //得到檔名稱
            String fileName=UUID.randomUUID().toString().replace("-", "")+"_"+list.get(1).getName();
            //校驗圖片的格式
            if(!fileName.toLowerCase().endsWith("jpg")){
                System.out.println("圖片格式不是jpg");
                request.setAttribute("msg", "你的圖片格式不是jpg格式");
                request.getRequestDispatcher("/adminjsps/admin/book/add.jsp").forward(request, response);
                return;
            }
            //使用目錄和檔名稱建立目標檔案
            File f=new File(path,fileName);
            //儲存檔案
            list.get(1).write(f);
            //校驗圖片的尺寸
            Image image=new ImageIcon(f.getAbsolutePath()).getImage();
            if(image.getWidth(null)>200 || image.getHeight(null)>200){
                f.delete();
                request.setAttribute("msg", "圖片的尺寸太大");
                request.getRequestDispatcher("/adminjsps/admin/book/add.jsp").forward(request, response);

            }
            //設定book的屬性
            b.setImage("book_img/"+fileName);
            s.add(b);
            request.setAttribute("msg", "新增成功");
            request.getRequestDispatcher("/adminjsps/admin/book/add.jsp").forward(request, response);
            System.out.println("fileName:"+fileName);
            System.out.println(path);
        } catch (FileUploadException e) {
            if(e instanceof FileUploadBase.FileSizeLimitExceededException){

                System.out.println("你上傳的檔案大於15K");
                request.setAttribute("msg", "你的圖片大於15k");
                request.getRequestDispatcher("/adminjsps/admin/book/add.jsp").forward(request, response);
                return;
            }

            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


    }

}
--------------------- 
作者:我想C 
來源:CSDN 
原文:https://blog.csdn.net/zllww123/article/details/77587292 
版權宣告:本文為博主原創文章,轉載請附上博文連結!