UTF-8 Имя кодировки в загруженном файле

21

Я пытаюсь позволить пользователю загрузить файл excel с японским именем. Кажется, что он работает только с IE8 и с другим IE и firefox, он не работает. Пожалуйста, предложите мне, как это сделать.

String fileName = dateString+"_マイページ情報.xls";
byte[] data = writer.getData();
response.setContentType("application/ms-excel");
response.setContentLength(data.length);
response.setHeader("Expires:", "0"); // eliminates browser caching
response.setHeader("Content-Disposition","attachment; filename="+URLEncoder.encode(fileName));
    
задан zawhtut 05.08.2013 в 06:44
источник

5 ответов

34

Я решил его решить следующим образом.

fileName = dateString+"_マイページ情報.xls"; 
fileName = URLEncoder.encode(fileName,"UTF-8"); 
try {
        response.setContentType("application/ms-excel; charset=UTF-8");
        response.setCharacterEncoding("UTF-8");
        if(browserType.equals("IE")||browserType.equals("Chrome"))
            response.setHeader("Content-Disposition","attachment; filename="+fileName);
        if(browserType.endsWith("Firefox"))
            response.setHeader("Content-Disposition","attachment; filename*=UTF-8''"+fileName);
    } catch (Exception e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    
ответ дан zawhtut 05.08.2013 в 12:32
  • @zawhtut, какой код вы используете для получения типа браузера? –  Mahmoud Saleh 22.03.2015 в 09:37
  • request.getHeader («User-Agent»); Я думаю. Это было долгое время, когда я опубликовал этот ответ и теперь не могу вспомнить многое. –  zawhtut 22.03.2015 в 09:47
  • Это сообщение в блоге очень полезно при решении таких проблем blogs.msdn.com/b/ieinternals/archive/2010/06/07/... и узнать сведения о браузере fromdev.com/2009/06/dealing- с-другом-клиент-browsers.html –  rakeeee 21.05.2015 в 06:08
  • Одной из наиболее частых причин этой проблемы являются пробелы между именем файла и типом файла, особенно в IE. –  Amir Amiri 21.02.2018 в 13:56
  • @rakeeee Спасибо за ссылку. Исходя из этого, я придумал другое решение, используя перенаправление. Самое приятное то, что он не требует кода, специфичного для браузера. См. Мой ответ ниже. –  yngwietiger 07.08.2018 в 18:37
9

Использовать метод setCharacterEncoding

  

Устанавливает кодировку символов (MIME-кодировку) отправляемого ответа   к клиенту, например, к UTF-8. Если кодировка символов   уже установлен setContentType (java.lang.String) или   setLocale (java.util.Locale), этот метод переопределяет его. призвание   setContentType (java.lang.String) со строкой text / html и   вызов этого метода со строкой UTF-8 эквивалентен   вызов setContentType со строкой text / html; кодировка = UTF-8.

     

Этот метод можно вызывать повторно, чтобы изменить кодировку символов.   Этот метод не действует, если он вызывается после того, как getWriter был   или после ответа.

Измените код следующим образом:

response.setContentType("application/ms-excel; charset=UTF-8");
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Disposition","attachment; filename="+URLEncoder.encode(fileName, "UTF-8"));
    
ответ дан Ankur Lathi 05.08.2013 в 06:50
  • Это отлично работало в Chrome. Но не работал для меня в Safari и Firefox. Оба назвали файл в соответствии с атрибутом «filename», закодированным в URL-адресе. –  yngwietiger 15.08.2018 в 14:56
  • @yngwietiger: попробуйте использовать это для firefox-response.setHeader («Content-Disposition», «attachment; filename * = UTF-8» или «fileName»); –  Ankur Lathi 25.08.2018 в 19:25
5

В вызове URLEncoder передайте второй необязательный аргумент «UTF-8». См. Ссылка

    
ответ дан Tom 05.08.2013 в 06:53
  • это сработало для меня –  Abhishek K 22.01.2015 в 13:18
1

Вот что я сделал, и он работает в браузерах ВСЕ , которые я пробовал (Chrome, Firefox и Safari). Кроме того, мне не нужно было писать какой-либо код, специфичный для браузера.

Согласно этой ссылке: Ссылка

  

все браузеры попытаются получить имя файла из пути   компонент URL

Итак, если браузер запрашивает URL-адрес с именем файла в конце, он правильно назовет файл. Это похоже на все браузеры.

В моем личном случае клиент не знает имя файла, которое он хочет загрузить. Наша система делает GET для файла на основе идентификатора. Например:

/api/file/download/<file_id>

Итак, я сделал, чтобы этот API просмотрел имя файла (мы храним его в db, file_id), URL-кодируем его и перенаправляем во второй API, который включает в себя имя файла. Например:

/api/file/download/<file_id>/<url-encoded filename>

Затем второй API будет использовать file_id для поиска и потоковой передачи содержимого файла, а браузер будет использовать часть имени файла, чтобы назвать загруженный файл.

ПРИМЕЧАНИЕ. Второй API игнорирует имя файла (ему это не нужно). Он также устанавливает заголовок Content-Disposition в «attachment;» только (НЕ задайте имя файла. Пусть браузер получит его из URL-адреса.)

    
ответ дан yngwietiger 07.08.2018 в 18:34
  • Похоже, что вы в хорошей форме, но, как примечание для других читателей, будьте предельно внимательны к тому, чтобы включать пользовательский ввод (например, имя файла с кодировкой URL здесь) в пути к файлам, которые вы используете на сервере. Это открывает двери для обхода пути. Вместо этого используйте идентификатор для файлов и сохраните фактическое имя файла в базе данных; в качестве альтернативы, установить безопасный шаблон для имен файлов и проверить ввод пользователя на этот шаблон. –  erickson 07.08.2018 в 18:45
-1
  

Не нужно устанавливать setCharacterEncoding и все, что просто добавить ниже строки   его работы прекрасны.

String fileName = URLEncoder.encode(fileName, "UTF-8");
response.setHeader("Content-Disposition","attachment; filename="+fileName );
    
ответ дан kiran 15.07.2016 в 09:14
  • ваш код не работает, по крайней мере, в FF. –  nllsdfx 19.01.2017 в 10:13