Загрузка файла AJAX с Express приводит к «этот сайт пытался загрузить несколько файлов» (Chrome)

#javascript #ajax #express #svelte

#javascript #аякс #выражать #стройный

Вопрос:

Почему это так запутанно? Я хочу загрузить файл, и я получаю эту ошибку:

 this site attempted to download multiple files
 

Как я могу предотвратить эту ошибку и фактически загрузить файл?

Если я отключу блок, он будет работать нормально… Но это действительно плохой UX — заставлять клиента делать это.

что это такое, что я запускаю здесь, поскольку я загружаю только один файл?

Я использую фреймворк svelte, если это что-то изменит.

клиент

 async function downloadFile(fieldId, fileName) {
        let response = await fetchGetFile(`/api/files/${fieldId}`);
        let blob = await response.blob();
        let url = window.URL.createObjectURL(blob);

        let a = document.createElement("a");
        a.style.display = "none";
        a.href = url;
        a.download = fileName;

        document.body.appendChild(a);
        a.click();
        window.URL.revokeObjectURL(url);
        a.remove();
    }
 

сервер

 router.get("/api/files/:fileId", async (req, res, next) => {
    try {
        let { fileId } = req.params;

        let query = `
            select *
            from file
            where id = ?
        `;

        let rows = await req.asyncQuery(query, [fileId]);

        let data = rows[0];

        let file = path.join(__dirname, `/../uploads/${data.fileName}`);

        res.download(file);
    } catch (err) {
        next(err);
    } finally {
        req.connection.release();
    }
});
 

Комментарии:

1. Насколько я могу судить, весь ваш клиентский код можно заменить window.open(`/api/files/${fieldId}`) . Попробуйте сначала.

2. Маршруты API авторизованы, т.Е. Должен быть предоставлен токен. Таким образом, это не может сработать. Тем не менее, я могу использовать window.URL.createObjectURL(blob) в качестве window.open() URL-адреса, но при этом файл не загружается, так как он открывает его в браузере.

3. Ошибка вызвана мерой безопасности в Chrome; я не вижу, как вы можете предотвратить это, если только вы не измените свой способ авторизации загрузок на файлы cookie, что должно заставить мое предложение работать.

4. unless you change your way of authorizing downloads to cookies Не могли бы вы, пожалуйста, немного пояснить это? Я не совсем понял.

5. Ваш сервер использует токен для авторизации, правильно? Это означает, что если вы используете вместо этого сеанс , файл cookie сеанса будет включен во все запросы, включая открытие окна / вкладки с одним из ваших URL-адресов. Таким образом, вы можете использовать window.open и по-прежнему авторизовывать пользователя.