我正在尝试从Ember Js上传带有ajax的csv文件,并在我的Rails应用程序中读取它。 我尝试了两种不同的方法。在第一个中,我试图从Ember发送文件,如下所示:
submitImport() {
var fd = new FormData();
var file = this.get('files')[0];
fd.append("csv_file", file);
return this.get('authAjax')
.request('/contacts/import/csv', {
method: 'POST',
processData: false,
contentType: false,
data: fd
});
}
但问题是我没有在rails应用程序中获得csv_file参数。 request.content_type是application/x-www-form-urlencoded
,我需要多部分表单。我可以使用reques.raw_post然后我得到类似这样的------WebKitFormBoundarymgBynUffnPTUPW3l\r\nContent-Disposition: form-data; name=\"csv_file\"; filename=\"elevatr_import.csv\"\r\nContent-Type: text/csv\r\n\r\ngeorgica,gica@me.com\nleo, leonard@yahoo.com\ngigel, becali@oita.fcsb\n\r\n------WebKitFormBoundarymgBynUffnPTUPW3l--\r\n
,我需要以某种方式解析这个,我真的不喜欢这个解决方案。
另一种方法是发送base64编码文件,然后从Rails解码。我试过这个:
`
submitImport() {
var fd = new FormData();
var file = this.get('files')[0];
this.send('getBase64', file);
var encoded_file = this.get('encoded_file');
return this.get('authAjax')
.request('/contacts/import/csv', {
method: 'POST',
data: { csv_file: encoded_file }
});
},
getBase64(file) {
var controller = this;
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function () {
controller.set('encoded_file', reader.result);
};
}
但由于某种原因,首先提交post请求,然后才调用getBase64方法。 有谁知道为什么会发生这种情况,或者我应该采用不同的方法?
由于
答案 0 :(得分:4)
<强> FORMDATA 强>
要使用multipart/form-data
发送,您有正确的想法,并且正在设置正确的选项,但authAjax
或其他设置可能会导致产生冲突的选项,从而导致内容类型为application/x-www-form-urlencoded
。
// this should make a request with a content-type of multipart/form-data
$.ajax({
url: 'upload/destination',
type: 'POST',
data: formDataObj,
contentType: false,
processData: false,
});
<强>的Base64 强>
在您提出请求后读取文件的原因是FileReader
异步工作。要作为base64编码的字符串发送,您需要在启动ajax请求之前等待读者完成。您可以在onloadend
活动后发出请求。
actions: {
submitImport() {
var file = this.get('files')[0];
this.encodeAndSendFile(file);
},
},
sendFile(base64File) {
return this.get('authAjax')
.request('/contacts/import/csv', {
method: 'POST',
data: { csv_file: encoded_file },
});
},
encodeAndSend(file) {
var controller = this;
var reader = new FileReader();
reader.onloadend = function () {
controller.sendFile(reader.result);
};
reader.readAsDataURL(file);
}