文件上传无论成败均返回204状态码,如何修改服务器端状态码?
问题分析与解决方案
核心问题原因
你的服务器端Store方法是void返回类型,在ASP.NET中,默认会给无返回值的Action返回204 No Content状态码——不管文件保存成功还是失败,客户端都会收到这个状态码。另外还有一个隐藏问题:客户端FormData中设置的文件键是"file1",但服务器端却在取"MyKey1",这会导致服务器找不到上传的文件,直接跳过保存逻辑,但依然返回204,让你误以为数据传递正常但状态码不对。
解决步骤
1. 修正客户端与服务器端的文件键匹配问题
客户端代码中你用formdata.append("file1", file[i]);,所以服务器端需要对应取"file1",而不是"MyKey1":
var httpPostedFile = HttpContext.Current.Request.Files["file1"];
2. 修改服务器端方法,自定义返回状态码和响应内容
将void返回类型改为ActionResult(如果是MVC)或者HttpResponseMessage(如果是Web API),这样就能根据操作结果返回不同的状态码和提示信息。
方案一:使用MVC的ActionResult返回
public ActionResult Store() { try { if (HttpContext.Current.Request.Files.AllKeys.Any()) { var httpPostedFile = HttpContext.Current.Request.Files["file1"]; if (httpPostedFile != null && httpPostedFile.ContentLength > 0) { var fileSaveDir = HttpContext.Current.Server.MapPath("MyKey"); if (!Directory.Exists(fileSaveDir)) { Directory.CreateDirectory(fileSaveDir); } // 可选:添加时间戳避免文件名重复 var fileName = $"{Path.GetFileNameWithoutExtension(httpPostedFile.FileName)}_{DateTime.Now:yyyyMMddHHmmss}{Path.GetExtension(httpPostedFile.FileName)}"; var fileSavePath = Path.Combine(fileSaveDir, fileName); httpPostedFile.SaveAs(fileSavePath); // 上传成功,返回200 OK和成功消息 return Json(new { success = true, message = "文件上传成功" }, JsonRequestBehavior.AllowGet); } // 没有找到有效文件,返回400 Bad Request return Json(new { success = false, message = "未上传有效文件" }, HttpStatusCode.BadRequest); } // 没有文件上传,返回400 Bad Request return Json(new { success = false, message = "未检测到上传文件" }, HttpStatusCode.BadRequest); } catch (Exception ex) { // 捕获异常,返回500 Internal Server Error和错误信息 return Json(new { success = false, message = $"文件上传失败:{ex.Message}" }, HttpStatusCode.InternalServerError); } }
方案二:使用Web API的HttpResponseMessage返回
如果你的接口是Web API,可以这样写:
public HttpResponseMessage Store() { try { if (HttpContext.Current.Request.Files.AllKeys.Any()) { var httpPostedFile = HttpContext.Current.Request.Files["file1"]; if (httpPostedFile != null && httpPostedFile.ContentLength > 0) { var fileSaveDir = HttpContext.Current.Server.MapPath("MyKey"); if (!Directory.Exists(fileSaveDir)) { Directory.CreateDirectory(fileSaveDir); } var fileName = $"{Path.GetFileNameWithoutExtension(httpPostedFile.FileName)}_{DateTime.Now:yyyyMMddHHmmss}{Path.GetExtension(httpPostedFile.FileName)}"; var fileSavePath = Path.Combine(fileSaveDir, fileName); httpPostedFile.SaveAs(fileSavePath); return Request.CreateResponse(HttpStatusCode.OK, new { success = true, message = "文件上传成功" }); } return Request.CreateResponse(HttpStatusCode.BadRequest, new { success = false, message = "未上传有效文件" }); } return Request.CreateResponse(HttpStatusCode.BadRequest, new { success = false, message = "未检测到上传文件" }); } catch (Exception ex) { return Request.CreateResponse(HttpStatusCode.InternalServerError, new { success = false, message = $"文件上传失败:{ex.Message}" }); } }
3. 客户端完善completeHandler逻辑
现在服务器会返回不同的状态码和响应内容,客户端可以在completeHandler中根据状态码判断结果:
function completeHandler(event) { const ajax = event.target; if (ajax.status === 200) { const response = JSON.parse(ajax.responseText); console.log(response.message); // 处理上传成功的逻辑,比如更新页面提示 } else if (ajax.status === 400) { const response = JSON.parse(ajax.responseText); console.error("上传失败:", response.message); // 处理参数错误的逻辑,比如提示用户重新选择文件 } else if (ajax.status === 500) { const response = JSON.parse(ajax.responseText); console.error("服务器错误:", response.message); // 处理服务器内部错误的逻辑,比如提示用户稍后重试 } else { console.error("未知错误,状态码:", ajax.status); } }
额外建议
- 可以在服务器端添加文件大小、格式的校验(比如限制只允许图片、文档类型),进一步提升接口的健壮性。
- 若上传大文件,建议在服务器端配置请求超时和最大上传文件大小参数,避免请求被中断。
内容的提问来源于stack exchange,提问作者Karthik Ravichandran
相关产品推荐
相关产品推荐

