from data请求ajax

本文介绍了如何使用FormData对象通过Ajax方式上传文件,包括HTML表单设置、JavaScript操作FormData及AJAX配置等关键步骤。
通过 传统的form表单提交的方式上传文件:
Html代码   收藏代码
  1. <form id"uploadForm" action"http://localhost:8080/cfJAX_RS/rest/file/upload" method"post" enctype ="multipart/form-data">  
  2.      <h1 >测试通过Rest接口上传文件 </h1>  
  3.      <p >指定文件名: <input type ="text" name="filename" /></p>  
  4.      <p >上传文件: <input type ="file" name="file" /></p>  
  5.      <p >关键字1: <input type ="text" name="keyword" /></p>  
  6.      <p >关键字2: <input type ="text" name="keyword" /></p>  
  7.      <p >关键字3: <input type ="text" name="keyword" /></p>  
  8.      <input type ="submit" value="上传"/>  
  9. </form>  

 

不过传统的form表单提交会导致页面刷新, 但是在有些情况下,我们不希望页面被刷新,这种时候我们都是使用Ajax的方式进行请求的:
Js代码   收藏代码
  1. $.ajax({  
  2.      url : "http://localhost:8080/STS/rest/user",  
  3.      type : "POST",  
  4.      data : $( '#postForm').serialize(),  
  5.      success : function(data) {  
  6.           $( '#serverResponse').html(data);  
  7.      },  
  8.      error : function(data) {  
  9.           $( '#serverResponse').html(data.status + " : " + data.statusText + " : " + data.responseText);  
  10.      }  
  11. });  

 

如上,通过 $( '#postForm' ).serialize() 可以对form表单进行序列化,从而将form表单中的所有参数传递到服务端。
 
但是上述方式,只能传递一般的参数, 上传文件的文件流是无法被序列化并传递的。
不过如今主流浏览器都开始支持一个叫做FormData的对象,有了这个FormData,我们就可以轻松地使用Ajax方式进行文件 上传 了。

 

 

关于FormData及其用法


FormData是什么呢?我们来看看Mozilla上的介绍。
XMLHttpRequest Level 2添加了一个新的接口 FormData.利用 FormData对象,我们可以通过JavaScript用一些键值对来模拟一系列表单控件,我们还可以使用XMLHttpRequest的 send()方法来异步的提交这个"表单".比起普通的ajax,使用 FormData的最大优点就是我们可以异步上传一个二进制文件. 
 
所有主流浏览器的较新版本都已经支持这个对象了,比如Chrome 7+、Firefox 4+、IE 10+、Opera 12+、Safari 5+。
 
参见: https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/FormData

 

 

这里只展示一个通过from表单来初始化FormData的方式
< form   enctype = "multipart/form-data"   method = "post"   name = "fileinfo" >
Js代码   收藏代码
  1. var oData = new FormData(document.forms.namedItem("fileinfo" ));  
  2. oData.append( "CustomField""This is some extra data" );  
  3. var oReq = new XMLHttpRequest();  
  4. oReq.open( "POST""stash.php" , true );  
  5. oReq.onload = function(oEvent) {  
  6.       if (oReq.status == 200) {  
  7.           oOutput.innerHTML = "Uploaded!" ;  
  8.      } else {  
  9.           oOutput.innerHTML = "Error " + oReq.status + " occurred uploading your file.<br \/>";  
  10.      }  
  11. };  
  12. oReq.send(oData);  

 

 
 
使用FormData,进行Ajax请求并上传文件

这里使用JQuery,但是老版本的JQuery比如1.2是不支持的,最好使用2.0或更新版本:
Html代码   收藏代码
  1. <form id"uploadForm">  
  2.       <p >指定文件名: <input type="text" name="filename" value""/></p >  
  3.       <p >上传文件: <input type="file" name="file"/></ p>  
  4.       <input type="button" value="上传" onclick="doUpload()" />  
  5. </form>  

 

Js代码   收藏代码
  1. function doUpload() {  
  2.      var formData = new FormData($( "#uploadForm" )[0]);  
  3.      $.ajax({  
  4.           url: 'http://localhost:8080/cfJAX_RS/rest/file/upload' ,  
  5.           type: 'POST',  
  6.           data: formData,  
  7.           async: false,  
  8.           cache: false,  
  9.           contentType: false,  
  10.           processData: false,  
  11.           success: function (returndata) {  
  12.               alert(returndata);  
  13.           },  
  14.           error: function (returndata) {  
  15.               alert(returndata);  
  16.           }  
  17.      });  
  18. }  
<think>我们正在处理一个关于使用FormData和MultipartFile进行文件上传的问题。用户希望了解如何通过FormData请求处理MultipartFile文件上传。根据提供的引用,我们可以总结出以下关键点: 1. 前端使用FormData对象来构建表单数据,特别是多文件上传时,可以循环添加多个文件。 2. 前端通过AJAX(如jQuery的$.ajax)发送FormData数据,注意设置`contentType: false`和`processData: false`,以确保正确发送multipart/form-data请求。 3. 后端使用Spring框架的`MultipartFile`或`MultipartHttpServletRequest`来接收上传的文件。 根据这些信息,我们可以分步骤说明前后端的实现。 ### 前端实现步骤(使用JavaScript/jQuery): 1. 创建一个FormData对象。 2. 将选中的文件(可以是多个)添加到FormData对象中。注意,如果多个文件使用同一个字段名(如"file"),则后端需要用数组或列表接收;如果每个文件字段名不同,则分别添加。 3. 使用AJAX发送FormData对象,设置正确的选项(contentType和processData为false)。 ### 后端实现步骤(使用Spring Boot): 1. 在控制器方法中,使用`@RequestParam`注解和`MultipartFile`类型参数接收单个文件,或者使用`MultipartFile[]`接收多个文件(如果前端用同一个字段名上传多个文件)。 2. 也可以使用`MultipartHttpServletRequest`来获取文件,但推荐使用`MultipartFile`,更简洁。 ### 示例代码: #### 前端代码(参考引用[2]): ```javascript // 假设有一个id为"fileInput"的文件输入框(支持多选) function uploadFiles() { var formData = new FormData(); var files = $('#fileInput')[0].files; // 获取文件列表 // 将每个文件添加到FormData中,使用同一个字段名"files" for (var i = 0; i < files.length; i++) { formData.append("files", files[i]); } // 可以添加其他参数 formData.append("param1", "value1"); $.ajax({ url: '/upload', type: 'POST', data: formData, contentType: false, // 必须 processData: false, // 必须 success: function(response) { console.log('上传成功', response); }, error: function() { console.error('上传失败'); } }); } ``` #### 后端代码(Spring Boot控制器): ```java import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; @RestController public class FileUploadController { @PostMapping("/upload") public String handleFileUpload(@RequestParam("files") MultipartFile[] files, @RequestParam("param1") String param1) { // 处理参数 System.out.println("接收参数: " + param1); // 处理上传的文件 for (MultipartFile file : files) { if (!file.isEmpty()) { // 这里可以保存文件或进行其他处理 String fileName = file.getOriginalFilename(); // 保存文件等操作... System.out.println("上传文件: " + fileName); } } return "上传成功"; } } ``` ### 注意事项: 1. 前端发送的字段名(如"files")必须与后端`@RequestParam`中的名称一致。 2. 如果需要上传其他参数,可以像添加文件一样添加到FormData中。 3. 后端也可以使用`List<MultipartFile> files`来接收多个文件,但字段名需要一致。 4. 文件大小限制:在Spring Boot中,可以在`application.properties`中设置: ```properties spring.servlet.multipart.max-file-size=10MB spring.servlet.multipart.max-request-size=10MB ``` ### 相关问题 1. 如何解决Spring Boot中文件上传大小限制的问题? 2. 如何实现多文件上传并分别保存? 3. 文件上传过程中如何保证安全性? 4. 如何实现文件上传的进度条显示? [^1]: [SpringBoot - 文件上传 - FormDataajax、以及MultipartFile接收](https://example.com/ref1) [^2]: [js 使用FormData实现多文件上传](https://example.com/ref2) [^3]: [工具发送formdata请求 Multipartfile 接收](https://example.com/ref3) [^4]: [SpringBoot2.1.x,okhttp3网络请求之MultipartFile方式上传文件](https://example.com/ref4)</think>### FormData请求处理MultipartFile文件上传指南 使用FormData处理MultipartFile文件上传需要前后端协同工作,以下是完整实现方案: #### 前端实现(JavaScript/jQuery) ```javascript // 获取文件并构建FormData function uploadFile() { const formData = new FormData(); const fileInput = document.getElementById('fileInput'); // 添加文件(支持多文件) for (let i = 0; i < fileInput.files.length; i++) { formData.append('files', fileInput.files[i]); // 'files'需与后端参数名匹配 } // 添加其他参数(可选) formData.append('userId', '12345'); // 发送AJAX请求 $.ajax({ url: '/api/upload', type: 'POST', data: formData, contentType: false, // 关键:禁用默认内容类型 processData: false, // 关键:禁止数据处理 success: (res) => console.log('上传成功', res), error: (err) => console.error('上传失败', err) }); } ``` #### 后端实现(Spring Boot) ```java @RestController public class FileController { // 接收单个文件 @PostMapping("/api/upload") public ResponseEntity<String> uploadFile( @RequestParam("files") MultipartFile file, // 参数名需与前端的'files'一致 @RequestParam(required = false) String userId) { if (file.isEmpty()) { return ResponseEntity.badRequest().body("文件为空"); } try { // 保存文件(示例) Path path = Paths.get("/uploads/" + file.getOriginalFilename()); Files.write(path, file.getBytes()); return ResponseEntity.ok("上传成功"); } catch (IOException e) { return ResponseEntity.status(500).body("上传失败"); } } // 接收多文件版本 public ResponseEntity<String> uploadMultipleFiles( @RequestParam("files") MultipartFile[] files) { // 遍历处理每个文件 } } ``` #### 关键配置(application.properties) ```properties # 设置文件大小限制(默认1MB) spring.servlet.multipart.max-file-size=10MB spring.servlet.multipart.max-request-size=10MB ``` #### 注意事项 1. **Content-Type设置** 前端必须设置`contentType: false`,浏览器会自动生成`multipart/form-data`边界标识[^1][^2] 2. **参数名一致性** 前端`formData.append('files')`与后端`@RequestParam("files")`必须使用相同名称 3. **多文件处理** - 前端:循环添加多个文件到同一个字段名 - 后端:使用`MultipartFile[]`接收文件数组[^2] 4. **文件大小限制** 超过配置大小时会抛出`SizeLimitExceededException`,需全局异常处理[^1] 5. **安全建议** ```java // 防止路径遍历攻击 String fileName = file.getOriginalFilename(); Path path = Paths.get("/safe_dir/", fileName).normalize().toAbsolutePath(); if (!path.startsWith("/safe_dir/")) { throw new IllegalArgumentException("非法文件名"); } ``` ### 常见问题解决方案 | 问题现象 | 解决方法 | |---------|---------| | 接收文件为null | 检查前端字段名是否与`@RequestParam`一致 | | 文件大小限制错误 | 调整`max-file-size`配置或捕获`SizeLimitExceededException` | | 中文文件名乱码 | 前端设置:`<meta charset="UTF-8">`,后端添加`spring.http.encoding.force=true` | | 跨域问题 | 添加`@CrossOrigin`注解或配置CORS过滤器 | ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值