В Angular 6 после размещения большого файла в оперативной памяти Mozilla стремительно растет - PullRequest
0 голосов
/ 10 сентября 2018

У меня есть приложение Angular 6, которое загружает один файл, используя POST:

представить-form.component.html

<input type="file" id="file" (change)="onFileChange($event.target.files)">
<button (click)="uploadFile()"> Upload </button>

Submit-form.component.ts

import { Component, OnInit } from '@angular/core';
import { HttpResponse, HttpEventType } from '@angular/common/http';

import { FileService } from '../file.service';

@Component({
    selector: 'app-submit-form',
    templateUrl: './submit-form.component.html',
    styleUrls: ['./submit-form.component.css']
})
export class SubmitFormComponent implements OnInit {
    constructor( private fileService: FileService) { }

    file_to_upload: File;

    onFileChange(files: FileList) {
        this.file_to_upload = files.item(0);
    }

    uploadFile() {
        this.fileService.uploadFile(this.file_to_upload).subscribe(
            (event) => {
                if (event.type == HttpEventType.UploadProgress) {
                    const percentDone = Math.round(100 * event.loaded / event.total);
                    console.log(`Uploading - %${percentDone}...`);
                } else if (event instanceof HttpResponse) {
                    console.log('File completely loaded!');
                }
            },
            (err) => {
                console.log('Upload Error', JSON.stringify(err));
            }, () => {
                console.log('Done uploading file!');
            }
        );
    }
}

file.service.ts

import { Injectable } from '@angular/core';

import { HttpClient, HttpParams, HttpRequest } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({
    providedIn: 'root'
})
export class FileService {
    private uploadUrl = 'http://localhost:4200/upload';
    constructor(private http: HttpClient) { }

    uploadFile(file: File): Observable<any> {
        var formData = new FormData();
        formData.append('file_to_upload', file, file.name);

        var params = new HttpParams();
        var httpOptions = {
            params: params,
            reportProgress: true
        };

        const req = new HttpRequest('POST', this.uploadUrl, formData, httpOptions);
        return this.http.request(req);
    }
}

И сервер Node.JS, который сохраняет этот файл, используя multer:

server.js

const http = require('http')
const url = require('url')
const path = require('path')
const multer = require('multer')
const express = require('express')

const router = express()
const serverPort = 4200;

router.use((req, res, next) => {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
    next();
});

var storage = multer.diskStorage({
    destination: (req, file, cb) => cb(null, 'data/upload/'),
    filename: (req, file, cb) => {
        console.log('Upload file ', file)
        cb(null, file.originalname)
    }
});
var upload = multer({storage: storage});


router.post('/upload', upload.single('file_to_upload'), (req, res) => {
    res.json({'Code': 200, 'Message': 'Success'});
});

router.listen(serverPort, () => console.log(`Server running at http://localhost:${serverPort}/`));

В Mozilla он отлично работает с небольшими файлами (<500 МБ), но когда я загружаю что-то большее, браузер зависает между <code>Uploading - 100% и File completely loaded!, быстро увеличивает потребление памяти примерно в 1,5 раза, а затем мгновенно падает отступить, вывести File completely loaded! и Done uploading file! (судя по папке data/upload/, файл завершает загрузку где-то в начале скачка памяти). В Chrome размер файла не имеет значения - он всегда работает правильно (даже с> 3 ГБ файлами).

Если я использую HTML <form> для загрузки файла, например:

<form action="http://localhost:4200/upload" method="POST" enctype="multipart/form-data">
    <input type="file" name="file_to_upload" >
    <input type="submit" value="Upload">
</form>

... тогда в обоих браузерах нет резких скачков памяти. Итак, что происходит?

...