Поврежденная загрузка файла в Chrome с работником сервиса - PullRequest
0 голосов
/ 27 декабря 2018

У нас есть Angular Web App с сервисными работниками для базового кэширования.Бэкэнд представляет собой Java-приложение Spring Boot, которое предоставляет различные сервисы через интерфейсы REST.Среди прочего у нас есть GET-запросы на загрузку файлов.

Все месяцами все работало нормально, но начиная с Chrome v71 у нас возникает следующая проблема: если мы загружаем файл через службу REST, загрузка сама завершается, ноесли мы попытаемся открыть его (например, PDF), это не сработает, поскольку файл поврежден.Причина в том, что файл загружен не полностью.Например, мы попробовали с PDF, который имеет размер 539 КБ.Во время нескольких загрузок мы всегда получали файлы разных размеров: 506 КБ, 504 КБ, 518 КБ, ... Иногда мы также получаем полный файл, и его можно открыть без проблем.Это происходит только в Chrome (мы не можем воспроизвести ни в каком другом браузере, ни в FF, ни в Safari, ни в IE).После нескольких часов отладки мы обнаружили, что это как-то связано с работниками сферы обслуживания.Если мы отменим регистрацию работника сервиса и запустим загрузку после этого, мы всегда получим полный файл.

Я проверил все изменения в Chrome v71 и обнаружил, что это касается API Background Fetch -> https://www.chromestatus.com/feature/5712608971718656.

Создание ResponseEntity для службы GET в бэкэнде (мы уже проверили, что атрибут Content-Length всегда установлен правильно):

private ResponseEntity<Resource> getResourceResponseEntity(ReportDTO pdf) {
    ByteArrayResource resource = new ByteArrayResource(pdf.getData());
    return ResponseEntity.ok()
            .header(CONTENT_DISPOSITION, "attachment; filename=" + pdf.getFilename())
            .header(CONTENT_LENGTH, 
String.valueOf(resource.contentLength()))
            .contentType(APPLICATION_PDF)
            .body(resource);
}

Конфигурация нашего сервисного работника (в основном, мы кэшируем некоторые активы иисключить каждый URL / api / ** (URL-адрес загрузки файла соответствует этому шаблону):

{
    "index": "/index.html",
    "assetGroups": [
        {
            "name": "app",
            "installMode": "prefetch",
            "resources": {
                "files": ["/assets/favicon.ico", "/index.html", "/*.css", "/*.js"]
            }
        },
        {
            "name": "assets",
            "installMode": "lazy",
            "updateMode": "prefetch",
            "resources": {
                "files": ["/assets/**", "!/assets/favicon.ico"]
            }
        }
    ],
    "dataGroups": [
        {
            "name": "api-disable-cache",
            "urls": ["/api/**", "/isAlive"],
            "cacheConfig": {
                "strategy": "freshness",
                "maxSize": 0,
                "maxAge": "0u"
            }
        }
    ]
}

Мы загружаем файл, открывая новое окно браузера с соответствующим URL-адресом для запроса GET:

window.open(url, '_blank');

Я также открою тикет для Chrome, чтобы они могли проверить, нужно ли это исправлять в реализации сервисного работника. В любом случае, если кто-то сталкивался с подобной проблемой или у кого есть идеякак это можно исправить (без полного отключения рабочих, что на самом деле является нашим текущим исправлением),пожалуйста, дай мне знать.Спасибо!

ОБНОВЛЕНИЕ: Соответствующий выпуск Chromium: https://bugs.chromium.org/p/chromium/issues/detail?id=917958&q=corrupt&colspec=ID%20Pri%20M%20Stars%20ReleaseBlock%20Component%20Status%20Owner%20Summary%20OS%20Modified

...