Próbuję przesłać pliki z aplikacji Angular 4 do usługi interfejsu JSON API, która akceptuje ciągi base64 jako treść pliku.Angular - prześlij plik jako base64
Więc to, co robię, to - przeczytaj plik z FileReader.readAsDataURL
, a kiedy użytkownik potwierdzi przesłanie, utworzę żądanie JSON do API i wyślę ciąg base64
pliku, który dostałem wcześniej.
To gdzie zaczyna problem - jak tylko coś zrobić z „zawartością” (log go wysłać go w/e) wniosek zostanie wysłany, ale jego szalenie wolno, na przykład 20 sekund dla pliku 2 MB.
Próbowałem:
- użyciu
ArrayBuffer
i ręcznie przekształcenie go do base64 - przechowywania ciąg base64 w HTML i pobieranie go później
- czyta pliki po kliknięciu przez użytkownika przycisku wysyłania
- używanie starego klienta z
@angular/common
- przy użyciu zwykłego żądania XHR
ale wszystko prowadzi do tego samego wyniku.
Wiem, gdzie leży problem. Ale dlaczego to się stało? Czy jest to coś specyficznego dla przeglądarki lub konkretnego kanciastego? Czy istnieje bardziej preferowane podejście (należy pamiętać, że musi to być łańcuch base64)?
Uwagi:
- zmieniania czegokolwiek w API jest poza moją kontrolą
- API jest w porządku, wysyłając dowolną listonosz plik koryta zakończy natychmiast
Kod:
Ten sposób działa, gdy użytkownik dodaje plik do zrzutowiska:
public onFileChange(files: File[]) : void {
files.forEach((file: File, index: number) => {
const reader = new FileReader;
// UploadedFile is just a simple model that contains filename, size, type and later base64 content
this.uploadedFiles[index] = new UploadedFile(file);
//region reader.onprogress
reader.onprogress = (event: ProgressEvent) => {
if (event.lengthComputable) {
this.uploadedFiles[index].updateProgress(
Math.round((event.loaded * 100)/event.total)
);
}
};
//endregion
//region reader.onloadend
reader.onloadend = (event: ProgressEvent) => {
const target: FileReader = <FileReader>event.target;
const content = target.result.split(',')[1];
this.uploadedFiles[index].contentLoaded(content);
};
//endregion
reader.readAsDataURL(file);
});
}
Metoda ta działa przy użytkowników kliknie przycisk Zapisz
public upload(uploadedFiles: UploadedFile[]) : Observable<null> {
const body: object = {
files: uploadedFiles.map((uploadedFile) => {
return {
filename: uploadedFile.name,
// SLOWDOWN HAPPENS HERE
content: uploadedFile.content
};
})
};
return this.http.post('file', body)
}
Pytasz o problem z kodem, ale nie publikujesz żadnej jego linii. –
@JB Nizet Dodałem odpowiedni kod – realshadow
Co się stanie, jeśli sam zbudujesz ciąg JSON za pomocą prostego łączenia ciągów (skoro wiesz, że base64 nie zawiera żadnych znaków, które muszą być zakodowane), zamiast pozwolić http to zrobić? –