【问题标题】:How to POST JSON and a file to web service with Angular?如何使用 Angular 将 JSON 和文件发布到 Web 服务?
【发布时间】:2013-08-13 07:31:53
【问题描述】:

如何使用 AngularJS 发送 POST 请求? JSON 部分是必需的,但文件不是。我已经根据其他博客文章尝试过这个,但它不起作用。我收到 Bad request 400 错误

正确答案加200分

var test = {
  description:"Test",
  status: "REJECTED"
};

var fd = new FormData();
fd.append('data', angular.toJson(test));

return $http.post('/servers', fd, {
  transformRequest: angular.identity,
  headers: {
    'Content-Type': undefined
  }
});

【问题讨论】:

  • 只是为了确保,您想在一个请求中同时发送编码文件 JSON 内容?你能澄清一下你想要得到的流程吗?
  • @Benjamin Gruenbaum:是的,这是正确的,所有在一个请求中。我创建了一个 Java Spring 后端,它采用必需的 JSON 部分和可选的文件部分。我有一个用户输入数据的表单,然后模型通过 angular.toJson(..) 转换为 Json,然后我想发布它。用户还可以选择以相同的形式上传文件。
  • 嗯,这可能是一个小工作或很多什么,你必须支持哪些浏览器?
  • 我不会关心古代浏览器。使用我的网页的人应该有一个 html5 浏览器。
  • FormData 绝对是要走的路,你似乎已经完成了一半,你正在将 JSON 数据附加到表单而不是文件,你应该在你的文件上调用 fd.append (或创建来自它的Blob)并发送。 (请参阅 FormData 上的 this tutorial,如果您对此有任何反馈,我也想听听 :))。一旦你设置了它,你仍然需要在 Spring 中支持 Multipart。这需要 goo.gl/iYguqz 。我也会使用普通的 XHR 而不是 $http,老实说,较新版本的 Angular 可能解决了 Angular 在 AJAX 中使用 FormData 时遇到的一些旧问题。

标签: javascript angularjs


【解决方案1】:

我已经用一个简单的 Spring 后端测试了你的代码,它工作正常:

@Controller
public class FileController {

  @ResponseBody
  @RequestMapping(value = "/data/fileupload", method = RequestMethod.POST)
  public String postFile(@RequestParam(value="file", required=false) MultipartFile file,
                       @RequestParam(value="data") Object data) throws Exception {
    System.out.println("data = " + data);

    return "OK!";
  }
}

我已将您的客户端代码与 angular v1.1.5 一起使用:

var test = {
  description:"Test",
  status: "REJECTED"
};

var fd = new FormData();
fd.append('data', angular.toJson(test));

//remove comment to append a file to the request
//var oBlob = new Blob(['test'], { type: "text/plain"});
//fd.append("file", oBlob,'test.txt');

return $http.post('/data/fileupload', fd, {
  transformRequest: angular.identity,
  headers: {
    'Content-Type': undefined
  }
});

请求如下所示(从 Chrome 控制台网络选项卡复制):

Request URL:http://localhost:8080/data/fileupload
Request Method:POST
Status Code:200 OK

Request Headers
POST /data/fileupload HTTP/1.1
Host: localhost:8080
...
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryEGiRWBFzWY6xwelb
Referer: http://localhost:8080/
...
Request Payload
------WebKitFormBoundaryEGiRWBFzWY6xwelb
Content-Disposition: form-data; name="data"

{"description":"Test","status":"REJECTED"}
------WebKitFormBoundaryEGiRWBFzWY6xwelb--

响应 200 OK,控制台输出预期的:{"description":"Test","status":"REJECTED"}

【讨论】:

  • 嗯...@RequestParam 你说,为什么@RequestPart 在这种情况下不正确。因为这就是我的应用程序中的内容。我会改变并检查它是否有效......但是知道为什么我应该使用它对我很有用:)
  • 还有数据参数,我可以改为声明正确的类型吗?还是我必须从控制器内的 Object 中投射它?
  • 首先,我应该提到我在我的 Spring 配置中使用了@Bean public MultipartResolver multipartResolver() {return new CommonsMultipartResolver();}。不确定@RequestPart@RequestParam。将数据参数声明为正确的类型应该不是问题,为了简单起见,我只是使用了 Object。
  • 我在 XML <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!--Max upload size is 8 MB--> <property name="maxUploadSize" value="8192000" /> </bean> 中有这个,但我不明白如何声明 @RequestParam("cat") Cat cat,而不是 Object?它似乎不起作用..
  • 由于数据部分是 JSON,我想自动将其转换为服务器端的 Domain 对象......就像我使用 @RequestBody@ResponseBody 时一样
【解决方案2】:

您可以在 POST 数据中直接发布 JSON 内容。

$http.post(URI, JSON.stringify(test));

根据 API 规范,您可能需要添加内容类型。

$http.post(URI, JSON.stringify(test), {headers: {'Content-Type': 'application/json'}});

【讨论】:

  • 很抱歉,被“需要 JSON 部分,但文件不是”所抛弃。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-21
  • 2013-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多