Как запустить загрузку браузера из браузера FETCH? - PullRequest
0 голосов
/ 10 марта 2020

Я работаю над проектом с Vue. js и Typescript для внешнего интерфейса и Java Spring в качестве внутреннего интерфейса.

Мой java контроллер извлекает данный отчет из БД и затем копирует его в ответ HTML. Я хочу, чтобы CSV загружался браузером, поэтому я добавил в ответ заголовок Content-disposition .

     @GetMapping('/download')
     public void downloadCSV(HttpServletRequest response){
        Report r = reportService.findById(85);
        response.addHeader("Content-Disposition", "attachment; filename=myCSV.csv");
        response.setContentType("text/csv");

        try {
            InputStream stream = new ByteArrayInputStream(r.getDocument());
            IOUtils.copy(stream, response.getOutputStream());
            response.flushBuffer();
        } catch(Exception e) {...}
     }

У меня есть 2 кнопки: один простой тег гиперссылки с ссылкой href на download () и кнопка b (из bootstrap - vue), которая при нажатии вызывает триггеры download2 () .

   <a :href="download" role="button"> Download CSV </a>

   <b-button @click="event => download2()">
      Download CSV v2
   </b-button>
    get download(): string {
        return 'http://localhost:8080/download';
    }


    async download2() {
        const rHeaders = new Headers();
        rHeaders.append('Accept', 'text/csv');

        const configInit = RequestInit = {
           method: 'GET',
           headers: rHeaders
        };

        try {
            const res = await fetch('http://localhost:8080/download', configInit);
            return res.text();
        } catch (e) {...}
    }

Теперь, если я нажму на первую кнопку «Скачать CSV», CSV будет правильно загружен браузером. Консоль javascript выводит следующее:

Resource interpreted as Document but transferred with MIME type text/csv

и в теле ответа ничего нет.

Вместо этого, если я нажимаю 2-ю кнопку «Загрузить CSV v2», загрузка выполняется не запускается, но у меня есть CSV в теле ответа.

Здесь различия в заголовках запроса между ними.

*Header*                   *Download csv*        *Download csv v2*
Sec-Fetch-Dest                document               empty
Sec-Fetch-Mode                navigate               cors
Sec-Fetch-User                   ?1                    -
Upgrade-Insecure-Requests        1                     -

остальные заголовки такие же. Изменить эти заголовки невозможно, даже если я установил их в методе javascript; они остаются прежними. В чем проблема? Спасибо.

1 Ответ

0 голосов
/ 11 марта 2020

Я нашел решение, "подражая" поведению элемента <a>:

Таким образом, он работает правильно:

async download2() {
    const configInit: RequestInit = {
        method: 'GET'
    };

    try {
       await fetch('http://localhost:8080/download', configInit)
          .then(response => response.blob())
          .then(blob => {
              const url = window.URL.createObjectURL(blob);
              const a = document.createElement('a');
              a.style.display = 'none';
              a.href = url;
              a.download = 'report.csv';
              document.body.appendChild(a);
              a.click();
              window.URL.revokeObjectURL(url);
          })
    } catch (e) {...}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...