Я пробовал 400 комбинаций синтаксисов и заголовков, я не могу понять, как сделать HTTP-вызов из Angular, чтобы получить файл с моего сервера NodeJS.
Найден в Stackoverflow и пробовал, но безрезультатно:
Скачать файл с http пост-запроса - Angular 6
Как скачать файл с HttpClient
Загрузить файл с сервера NodeJS с помощью Express
Как загрузить файл с Angular2
Это не может быть простой тег <a download>
или общедоступная папка express.static()
, потому что доступ к файлу ограничен, и мне нужно передать токен JWT (в Node у меня есть промежуточное ПО для экспресс-аутентификации, которое отклонит запрос, если токен не указан в заголовках или если он недействителен).
Файл представляет собой GZIP: ./dumps/dump.gz
и весит 812 Кб.
Мне удается загрузить файл, но что бы я ни пытался, он весит 1,4 МБ или 94 байта (неправильный размер) и не может быть открыт (7zip can't open file downloads/dump.gz as archive
).
Что я пробовал Угловая сторона (несколько попыток):
import { saveAs } from 'file-saver';
let headers = new Headers({
"Authorization": "Bearer " + user.jwt, // I need this in the headers
"Content-Type" : "application/octet-stream", // Tried with and without, "application/gzip", "application/json", no difference
"responseType": "blob" as "json", // Tried with and without, "text", "json", no difference
"Access-Control-Expose-Headers" : "Content-Disposition" // Tried with and without, no difference
})
this.http
.get("/download/dump", { headers })
.toPromise()
.then(res => {
const blob = new Blob([res["_body"]] , { type: "application/octet-stream;"} ); // Error : body is not a blob or an array buffer
// const blob = new Blob([res["_body"]]); // Same result
// const blob = new Blob([res.blob()]); // Error : body is not a blob or an array buffer
saveAs(blob, "dump.gz"); // Saves a big corrupted file
// window.URL.createObjectURL(new Blob(blob, {type: 'blob'})); Saves a 94 byte corrupted file. Tried {type: 'gzip'}, same thing
})
.catch(err => console.error("download error = ", err))
Что я пробовал Сторона узла (несколько попыток):
EDIT
Узел был невиновным, так как я мог получить файл напрямую из Chrome после отключения аутентификации. Итак, бэкэнд работает и проблема в Angular.
app.get( "/download/dump", authenticate, (req:Request, res:Response) => {
const file = path.resolve(__dirname, `./dumps/dump.gz`);
res
.set({ // Tried with and without headers, doesn't seem to do anything
"Content-Disposition" : "attachment", // Tried with and without
"filename" : "dump.gz", // Tried with and without
"filename*" : "dump.gz", // Tried with and without
"Content-Encoding" : "gzip", // Tried with and without
"Content-Type" : "application/gzip" // Tried with and without, "application/text", "application/json", no difference
})
.sendFile(file); // getting a big corrupted file
// .download(file); // Same result (big corrupted file)
})