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

请求体:

name=%22hello+world%22&file=temp.png&submit=submit

总结

  • (1)我们可以发现不管是post请求和get请求,他们的参数存在的形式都是不变的,通过key=value的形式存在。
  • (2)表单项type=filed只能获取获取文件的名字不能获取文件的内容。

3. 明确在enctype参数为multipart/form-data的时候post和get请求参数和请求体是什么形式的

get请求

请求头:

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

get请求

get请求和multipart/form-data结合无效,因为文件上传需要请求体。

post请求:

请求头:

POST /www.xxx.com HTTP/1.1

请求体:

------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--

通过观察发现这个的请求体就发生了变化。这种请求体被称之为多部件请求体。

什么是多部件请求体:就是把每一个表单项分割为一个部件。

因为表单项分为普通表单项和文件表单项,所以说部件也有区别。

  • 普通表单项:

    一个请求头:Content-Disposition: form-data; name=”name”

    一个请求体:里面就是我们表单的值”hello world”

  • 文件表单项:

    两个请求头:

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--

总结:参数获取不到主要是因为在使用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>
<script language="javascript">
function formSubmit(){
var action="fileftp.jsp";
action+="?otherName="+document.upload.otherName.value;
document.upload.action=action;
document.upload.submit();
}
</script>

(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();
}
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();
} } }

multipart/form-data 文件上传表单中 传递参数无法获取的原因!的更多相关文章

  1. spring boot:单文件上传/多文件上传/表单中多个文件域上传(spring boot 2.3.2)

    一,表单中有多个文件域时如何实现说明和文件的对应? 1,说明和文件对应 文件上传页面中,如果有多个文件域又有多个相对应的文件说明时, 文件和说明如何对应? 我们在表单中给对应的file变量和text变 ...

  2. python 处理form/data文件上传

    处理multipart/form-data 的java serverlet请求接口通过python实现 记住不要在头加:"Content-Type":"multipart ...

  3. 上传漏洞科普[1]-文件上传表单是Web安全主要威胁

    为了让最终用户将文件上传到您的网站,就像是给危及您的服务器的恶意用户打开了另一扇门.即便如此,在今天的现代互联网的Web应用程序,它是一种 常见的要求,因为它有助于提高您的业务效率.在Facebook ...

  4. 【Flask】 结合wtforms的文件上传表单

    表单中的文件上传 基本的表单渲染,表单类设置等等就不多说了,参看另一个文章即可.但是那篇文章里没有提到对于FileField,也就是上传文件的表单字段是如何处理,后端又是如何实现接受上传过来的文件的. ...

  5. 利用Formdata实现form提交文件上传不跳转页面

    作者:幻月九十链接:https://www.zhihu.com/question/19631256/answer/119911045来源:知乎著作权归作者所有,转载请联系作者获得授权. $('form ...

  6. Multipart/form-data POST文件上传详解

    Multipart/form-data POST文件上传详解 理论 简单的HTTP POST 大家通过HTTP向服务器发送POST请求提交数据,都是通过form表单提交的,代码如下: <form ...

  7. Multipart/form-data POST文件上传详解(转)

    Multipart/form-data POST文件上传详解 理论 简单的HTTP POST 大家通过HTTP向服务器发送POST请求提交数据,都是通过form表单提交的,代码如下: <form ...

  8. 构建multipart/form-data实现文件上传

    构建multipart/form-data实现文件上传 通常文件上传都是通过form表单中的file控件,并将form中的content-type设置为multipart/form-data.现在我们 ...

  9. form里面文件上传并预览

    其实form里面是不能嵌套form的,如果form里面有图片上传和其他input框,我们希望上传图片并预览图片,然后将其他input框填写完毕,再提交整个表单的话,有两种方式! 方式一:点击上传按钮的 ...

随机推荐

  1. php memcache 缓存与memcached 客户端的详细步骤

    缓存服务器有Memcache.Redis,我主要介绍了PHP中的Memcache,从Memcache简介开始,详细讲解了如Memcache和memcached的区别.PHP的 Memcache所有操作 ...

  2. Zabbix日志监控插件

    #!/usr/bin/env python # coding:utf-8 import re import os import sys import logging logging.basicConf ...

  3. java编程思想第四版第十三章字符串 总结

    1. String和StringBulider的使用 通过书中介绍, 我们得知如下结论: 当使用+连接符将字符串进行拼接的时候, 编译器会进行自动优化为使用StringBuilder连接字符串. 当在 ...

  4. thinkphp 5.1 去掉 .html 后缀

    thinkphp 5.1 去掉 .html 后缀  

  5. Bootstrap——面包屑导航(Breadcrumbs)

    面包屑导航(Breadcrumbs)是一种基于网站层次信息的显示方式. Bootstrap 中的面包屑导航(Breadcrumbs)是一个简单的带有 .breadcrumb 类的无序列表. <o ...

  6. BootStrap中的collapse插件堆叠效果

    通过网络上的一系列查找,总结出的collapse插件堆叠效果(网上没有找到,只能自己弄了,帮助那些和我遇到一样状况的同学) 首先感谢一位网友的知识总结给了我灵感,在这里先帮他推荐一波(https:// ...

  7. ACE框架 基于共享内存的进程间通讯

    ACE框架将基于共享内存的进程间通讯功能,如其它IO组件或IPC组件一样,设计成三个组件.流操作组件ACE_MEM_Stream,连接器组件ACE_MEM_Connector,以及接收连接组件ACE_ ...

  8. centos 更换用户密码

    腾讯云报告了我的服务器被暴力破解了.... 因此需要更换更复杂的password, 命令为:passwd  用户名,例如下我要更换root的password [root@VM_0_4_centos ~ ...

  9. Ubuntu改坏sudoers后无法使用sudo的解决办法

    练习安装odoo的时候,创建了一个odoo用户,想把它赋予sudo权限,然而,编辑的时候不留意,改坏了,导致sudo无法使用,无法编辑sudoers文件修改回来. 总提示如下信息: >>& ...

  10. 发送html邮件a标签中的url不显示的问题

    最近做的一个项目中,需要用到邮箱激活功能,但是遇到一个问题! 问题描述:发送邮箱之后,邮箱的激活链接的href属性不见了!!! 因为我采用的是本地的地址做测试,后来用百度的链接替换我的href地址又可 ...