2016-10-02 11 views
5

Próbuję przesłać plik csv z ajaxem z Ember Js i przeczytać go w mojej aplikacji Rails. Próbowałem dwóch różnych podejść. W pierwszym Próbowałam wysłać plik z Ember tak:Wysyłanie pliku CSV z Ember Js do Rails za pomocą Ajaxa

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 
    }); 
} 

ale problemem jest to, że nie dostanę param csv_file w aplikacji Rails. Typ request.content_type to application/x-www-form-urlencoded i potrzebuję formularza wieloczęściowego. Mógłbym użyć reques.raw_post, ale potem otrzymałem coś takiego: ------WebKitFormBoundarymgBynUffnPTUPW3l\r\nContent-Disposition: form-data; name=\"csv_file\"; filename=\"elevatr_import.csv\"\r\nContent-Type: text/csv\r\n\r\ngeorgica,[email protected]\nleo, [email protected]\ngigel, [email protected]\n\r\n------WebKitFormBoundarymgBynUffnPTUPW3l--\r\n i musiałbym jakoś to sparsować i nie podoba mi się to rozwiązanie.

Innym podejściem było wysłanie pliku base64 zakodowanego, a następnie odkodowanie go z Rails. Próbowałem to:

`

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); 
    }; 
} 

Ale z jakiegoś powodu, wniosek jest składany po raz pierwszy, a dopiero później, że metoda getBase64 nazywa. Czy ktoś wie, dlaczego tak się dzieje lub czy powinienem zastosować inne podejście?

Dzięki

Odpowiedz

3

FormData

Aby wysłać za pomocą multipart/form-data, masz dobry pomysł i wyznaczają odpowiednie opcje, ale to, że authAjax lub coś innego jest ustawienie opcji, które są przyczyną konfliktu jest możliwe, skutkując typem treści: 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

Powodem plik jest odczytywany po twój wniosek został złożony, że FileReader działa asynchronicznie. Aby wysłać jako łańcuch zakodowany w base64, musisz poczekać na ukończenie czytnika przed zainicjowaniem zapytania ajax. Możesz to zrobić, wysyłając żądanie po wydarzeniu 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); 
} 
+0

Dzięki za odpowiedź. Rzeczywiście mogłem kodować i wysyłać plik przy użyciu twojego kodu. Przyjrzę się także usłudze 'authAjax', być może będę w stanie to zrozumieć. –

Powiązane problemy