使用带有json和文件上载的Dojo xhr发送多部分表单

时间:2016-01-22 14:52:58

标签: javascript json ajax dojo form-data

我试图让这个工作,但没有找到任何解决方案。最接近我的问题的是这一个 - Composing multipart/form-data with a different Content-Type on each parts with Javascript (or Angular) - 但问题的作者在两者之间停了下来。我不能。

所以这就是故事 - 我用 .NET 编写了webservice。基于 POST - 我必须同时发送 - JSON 数据(包含标题,内容等)以及文件 - 仅从用户上传光盘。我是从 DOJO 对话框发送的。我实际上在做的是创建AJAX post请求并将其发送到服务器。

所以我应该使用' multipart / form-data' 。问题是我必须收集要从各种来源发送的数据(不仅仅是表单元素中提供的数据)。我的代码看起来像这样。

var values = { // here I create simple JS object with data from multiple places };
var formData = new FormData();

formData.append('data', json.stringify(values));   // Object to JSON
var files = document.getElementById("files").files;
var file = files[0];
formData.append("file0", file);

xhr.post('link_to_my_service',  
{ 
    handleAs: "json",
    sync: false,
    data: formData,
    headers: {                     
         'X-Requested-With': '',
         'Content-Type': false,   
         'Accept': 'application/javascript, application/json'
    }
}) // handlers are not important

它转到服务,服务接受它(' X-Requested-With'用于安全传递)。我在控制台中的请求看起来像这样。

------WebKitFormBoundaryDyeoTyKXhr5oZ1a9
Content-Disposition: form-data; name="data"    
{"key1":"value2","key2":"value1","key3":666,"key4":999}

------WebKitFormBoundaryDyeoTyKXhr5oZ1a9
Content-Disposition: form-data; name="file0"; filename="name_of_my_file.opml"
Content-Type: application/octet-stream

------WebKitFormBoundaryDyeoTyKXhr5oZ1a9--

它不起作用。这是因为数据'部分请求没有'内容类型'组!而且我无法以任何方式做到这一点。建议的解决方案是创建 BLOB ,然后将 JSON 字符串传递给它。但它也不起作用 - 它添加了内容类型' (虽然跳过charset),但是添加了文件名,并且在控制台中我看到这部分的实际内容是空的(虽然文件也一样 - 我不知道Chrome是否应该向我显示我的文件的完整数据)。 / p>

所以现在我被困 - 我不知道该怎么办。我无法改变服务。有没有人知道如何欺骗Dojo来实现我的目标?是的,我正在使用 Dojo 1.10

1 个答案:

答案 0 :(得分:2)

也许有点晚了,但迟到总比没有好。

您标记为最接近问题的链接已经提供了解决方案。 (Yeo的最后答案)

基于这个答案,我会尝试像这样构建我的FormData对象:

let formData = new FormData();

// add the file to your form data.
formData.append('file', file);    

// create an object like structure in your form data.
for (let key in values) {
  if(values.hasOwnProperty(key)) {
    formData.append(`data[${key}]`, values[key]);
  }
}

// set up your post requests options.
...

let handle = xhr.post(url, options);

然后在服务器端,您可以通过迭代请求正文部分并收集所需的字段来将其解析回对象。