簡體   English   中英

如何使用Express.JS接收多個請求

[英]How to receive multiple requests with Express.JS

我正在編寫Angular 6 + Express.JS應用程序,現在遇到了以下問題:當同時有多個請求時,有時(尤其是有四個以上的請求時)它們全部都以404響應甚至被取消。 我在Express中處理請求的方式是否存在任何問題,或者應該對並發請求進行一些調整?

要求:

let requests = [];
files.forEach((file) => {
    if (file.type.toLowerCase().includes('zip')) {
        requests.push(this.imagesService.uploadArchive(file).pipe(first()));
    } else {
        requests.push(this.imagesService.saveImage(file).pipe(first()));
    }
});

forkJoin(requests).subscribe(
    (res) => res.forEach(response => {
        this.onSave.emit(response);
    }), 
    (error) => {
        console.error(error);
    }, 
    () => {
        this.close.emit();
    }
);

快遞處理路線:

router.post('/images',
    formidable({
        encoding: 'utf-8',
        uploadDir: path.resolve(__dirname, '..', '..', 'uploads'),
        multiples: true,
        keepExtensions: true
    }),
    (req, res, next) => {
        const image = req.fields;
        const data = req.files;
        image.path = data.image.path;

        const file = fs.createReadStream(image.path);

        saveImage(image).then(
            result => {
                if (result) {
                    res.status(200).send(result);
                } else {
                    console.error("Cannot save image");
                    res.status(400).send("Cannot save image");
                }
        }).catch(e => console.error(e.stack));
});

回應:
response.png

更新

router.post('/archives',
    formidable({
        encoding: 'utf-8',
        uploadDir: path.resolve(__dirname, '..', '..', 'uploads'),
        multiples: true,
        keepExtensions: true
    }),
    (req, res, next) => {
        const data = req.files;

        let promises = [];

        fs.readFile(data.archive.path, async (err, archive) => {
            if (err) throw err;

            await extractImagesFromZip(archive, data.archive.path).then((images) =>
                images.forEach((image) => {
                    promises.push(
                        saveImage(image).then(
                            result => {
                                if (result) {
                                    result.path = result.path.split('/').pop();
                                    return result;
                                } else {
                                    console.error("Cannot save image " + image.name);
                                    fs.unlink(image.path, () => {});
                                }
                        }).catch(e => {
                            fs.unlink(image.path, () => {});
                            console.error(e.stack)
                        })
                    );
                })
            );

            Promise.all(promises)
            .then((result) => {
                if (result.length > 0) {
                    res.status(200).send(result)
                } else {
                    res.status(400).send("None images were saved")
                }
            }).catch((error) => {
                console.log(error.stack);
                res.status(400).send("None images were saved")
            });
        });
    }
);

export const extractImagesFromZip = (file, link) => {
    let promises = [];

    var zip = new JSZip();
    return zip.loadAsync(file)
    .then((archive) => {
        Object.values(archive.files).filter(
            f => 
                ['.jpg', '.jpeg', '.png'].some((suffix) => f.name.toLowerCase().endsWith(suffix))
                && ![...f.name.toLowerCase().split('/')].pop().startsWith('.')
                && !f.dir 
        ).forEach(f => promises.push(zip.file(f.name).async('nodebuffer').then((content) => {
            const ext = f.name.split('.').pop().toLowerCase();
            var dest = path.resolve(__dirname, '..', '..') + '/uploads/upload_'
                + crypto.randomBytes(Math.ceil(1322)).toString('hex').slice(0, 32).toLowerCase() 
                + '.' + ext;

            return new Promise((res, rej) => { 
                fs.writeFile(dest, content, (err) => { 
                    if (err) rej(err); 

                    res(new Promise((resolve, reject) => {
                        fs.readFile(dest, (erro, data) => {
                            if (erro) reject(erro);
                            if (data) resolve({ 
                                name: f.name, 
                                type: 'image/' + (ext === 'jpg' ? 'jpeg' : ext), 
                                path: dest 
                            });
                        });
                    }));
                });
            });
        })));

        fs.unlink(link, () => {});

        return Promise.all(promises);
    });
}

export const saveImage = (image) => {
    return database.raw(
        "INSERT INTO images (name, type, path) " +
        "VALUES (?, ?, ?) " +
        "RETURNING name, type, path, id",
        [image.name, image.type, image.path]
    ).then(data => data.rows[0]).catch(e => console.error(e.stack));
};

更新2

如果用戶和服務器都在localhost上,則一切正常,無論使用nginx或不使用nginx服務器都可以,但是當服務器處於遠程狀態時會出現問題

這樣的代碼有效

public async uploadFiles(files: File[]) {
    of(files)
        .pipe(
            concatMap(files =>
                files.map(file => {
                    return this.imagesService
                        .saveImage(file)
                        .pipe(
                            map(),
                            catchError((error, caught) => {
                                console.error(error);

                                return empty();
                            })
                        );
                })
            ),
            concatAll(),
            toArray(),
            map(res => console.log)
        )
        .subscribe();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM