“назовите” web pdf для лучшего сохранения имени файла по умолчанию в Acrobat?

StackOverflow https://stackoverflow.com/questions/151079

Вопрос

Мое приложение генерирует PDF-файлы для использования пользователем.HTTP-заголовок "Content-Disposition" устанавливается, как указано выше здесь.Для этого значения установлено значение "встроенный;filename=foo.pdf", чего должно быть достаточно, чтобы Acrobat указывал "foo.pdf" в качестве имени файла при сохранении pdf.

Однако при нажатии кнопки "Сохранить" во встроенном в браузер Acrobat по умолчанию для сохранения используется не это имя файла, а URL-адрес с косой чертой, измененной на подчеркивание.Огромный и уродливый.Есть ли способ повлиять на это имя файла по умолчанию в Adobe?

В URL-адресах есть строка запроса, и это не подлежит обсуждению.Это может быть важно, но добавление "&foo=/title.pdf" в конец URL-адреса не влияет на имя файла по умолчанию.

Обновление 2:Я пробовал и то, и другое

content-disposition  inline; filename=foo.pdf
Content-Type         application/pdf; filename=foo.pdf

и

content-disposition  inline; filename=foo.pdf
Content-Type         application/pdf; name=foo.pdf

(как проверено с помощью Firebug) К сожалению, ни то, ни другое не сработало.

Пример URL-адреса - это

/bar/sessions/958d8a22-0/views/1493881172/export?format=application/pdf&no-attachment=true

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

http___localhost_bar_sessions_958d8a22-0_views_1493881172_export_format=application_pdf&no-attachment=true.pdf

Обновление 3:Джулиан Решке привносит в это дело настоящее понимание и строгость.Пожалуйста, поддержите его ответ.Кажется, это нарушено в FF (https://bugzilla.mozilla.org/show_bug.cgi?id=433613) и IE, но работают в Opera, Safari и Chrome. http://greenbytes.de/tech/tc2231/#inlwithasciifilenamepdf

Это было полезно?

Решение

Частично проблема заключается в том, что соответствующие RFC 2183 на самом деле не указано, что делать с типом расположения "inline" и именем файла.

Кроме того, насколько я могу судить, единственным UA, который фактически использует имя файла для type=inline, является Firefox (см. тестовый пример).

Наконец, не очевидно, что API плагина действительно делает эту информацию доступной (возможно, кто-то, знакомый с API, сможет уточнить).

Тем не менее, я отправил указатель на этот вопрос сотруднику Adobe;может быть, нужные люди взглянут на это.

Похожие:смотрите попытку прояснить расположение содержимого в HTTP в черновик-решке-rfc2183-в-http -- это ранняя стадия работы, обратная связь приветствуется.

Обновить:Я добавил тестовый пример, что, по-видимому, указывает на то, что плагин Acrobat reader не использует заголовки ответов (в Firefox), хотя API плагина предоставляет к ним доступ.

Другие советы

Установите имя файла в ContentType ( Тип содержимого ) также хорошо.Это должно решить проблему.

context.Response.ContentType = "application/pdf; name=" + fileName;
// the usual stuff
context.Response.AddHeader("content-disposition", "inline; filename=" + fileName);

После установки заголовка content-disposition также добавьте заголовок content-length, затем используйте binarywrite для потоковой передачи PDF-файла.

context.Response.AddHeader("Content-Length", fileBytes.Length.ToString());
context.Response.BinaryWrite(fileBytes);

Как и ты, я много раз пытался заставить это сработать.В конце концов я отказался от этой идеи и просто выбрал обходной путь.

Я использую ASP.NET MVC Framework, поэтому я изменил свои маршруты для этого контроллера / действия, чтобы убедиться, что отправляемый PDF-файл является последней частью части местоположения URI (перед строкой запроса), и передаю все остальное в строке запроса.

Например:

Старый УРИ:

http://server/app/report/showpdf?param1=foo ¶m2=строка иимя файла=myreport.pdf

Новый URI:

http://server/app/report/showpdf/myreport.pdf?param1=foo ¶м2=бар

Результирующий заголовок выглядит точно так же, как вы описали (тип содержимого - application / pdf, расположение - встроенное, имя файла бесполезно является частью заголовка).Acrobat показывает его в окне браузера (диалог сохранения как отсутствует), а имя файла, которое автоматически заполняется, если пользователь нажимает кнопку Acrobat Сохранить, является именем отчета.

Несколько соображений:

Чтобы имена файлов выглядели прилично, в них не должно быть никаких экранированных символов (т. е. никаких пробелов и т.д.)...что немного ограничивает возможности.В этом случае мои имена файлов генерируются автоматически, и раньше в них были пробелы, которые отображались как '%20' в результирующем окне сохранения имени файла.Я просто заменил пробелы символами подчеркивания, и это сработало.

Это, безусловно, лучшее решение, но оно действительно работает.Это также означает, что у вас должно быть доступно имя файла, чтобы сделать его частью исходного URI, что может нарушить рабочий процесс вашей программы.Если оно в данный момент генерируется или извлекается из базы данных во время серверного вызова, генерирующего PDF-файл, вам может потребоваться переместить код, генерирующий имя файла, в javascript как часть отправки формы, или, если оно поступает из базы данных, выполнить быстрый вызов ajax для получения имени файла при создании URL, который приводит к получению встроенного PDF-файла.

Если вы берете имя файла из пользовательского ввода в форме, то оно должно быть проверено на отсутствие экранированных символов, которые будут раздражать пользователей.

Надеюсь, это поможет.

Попробуйте поместить имя файла в конец URL-адреса перед любыми другими параметрами.У меня это сработало.http://www.setasign.de/support/tips-and-tricks/filename-in-browser-plugin/

В ASP.NET 2.0 измените URL с

http://www. server.com/DocServe.aspx?DocId=XXXXXXX

Для

http://www. server.com/DocServe.aspx/MySaveAsFileName?DocId=XXXXXXX

Это работает для Acrobat 8, и по умолчанию сохраняется имя файла now MySaveAsFileName.pdf.

Однако вы должны ограничить допустимые символы в MySaveAsFileName (никаких периодов и т.д.).

Апачи mod_rewrite могу решить эту проблему.

У меня есть веб-сервис с конечной точкой по адресу /foo/getDoc.service.Конечно, Acrobat сохранит файлы как getDoc.pdf.Я добавил следующие строки в apache.conf:

LoadModule     RewriteModule         modules/mod_rewrite.so
RewriteEngine  on
RewriteRule    ^/foo/getDoc/(.*)$    /foo/getDoc.service     [P,NE]

Теперь, когда я прошу /foo/getDoc/filename.pdf?bar&qux, он будет внутренне переписан в /foo/getDoc.service?bar&qux, итак, я нажимаю на правильную конечную точку веб-службы, но Acrobat думает, что это сохранит мой файл как filename.pdf.

Если вы используете asp.net, вы можете управлять именем файла PDF с помощью имени страницы (URL).Как писали другие пользователи, Acrobat - это немного s...при нажатии кнопки "Сохранить" выберите имя PDF-файла:он берет название страницы, удаляет расширение и добавляет ".pdf".Итак, /foo/bar/GetMyPdf.aspx выдает GetMyPdf.pdf.

Единственное решение, которое я нашел, - это управлять "динамическими" названиями страниц с помощью asp.net обработчика:

  • создайте класс, реализующий IHttpHandler
  • сопоставьте обработчик в web.config, ограниченный классом

Отображение 1:все страницы имеют общий радиус (MyDocument_):

<httpHandlers>  
<add verb="*" path="MyDocument_*.ashx" type="ITextMiscWeb.MyDocumentHandler"/>

Отображение 2:полностью свободное имя файла (требуется указать путь к папке):

<add verb="*" path="/CustomName/*.ashx" type="ITextMiscWeb.MyDocumentHandler"/>

Несколько советов здесь (pdf-файл создается динамически с помощью iTextSharp):
http://fhtino.blogspot.com/2006/11/how-to-show-or-download-pdf-file-from.html

Вместо вложения вы можете попробовать встроенное:

Response.AddHeader("content-disposition", "inline;filename=MyFile.pdf");

Я использовал inline в предыдущем веб-приложении, которое генерировало выходные данные Crystal Reports в формате PDF и отправляло их пользователю в браузере.

Диалоговое окно загрузки файла (PDF) с возможностью сохранения и открытия

Моменты, которые нужно Запомнить:

  1. Возвращает поток с правильным размером массива из сервиса
  2. Считайте список байтов из потока с правильной длиной байта на основе длины потока.
  3. установите правильный тип содержимого

Вот код для чтения потока и открытия диалогового окна загрузки файла PDF

private void DownloadSharePointDocument()
{
    Uri uriAddress = new Uri("http://hyddlf5187:900/SharePointDownloadService/FulfillmentDownload.svc/GetDocumentByID/1/drmfree/");
    HttpWebRequest req = WebRequest.Create(uriAddress) as HttpWebRequest;
    // Get response   
    using (HttpWebResponse httpWebResponse = req.GetResponse() as HttpWebResponse)
    {
        Stream stream = httpWebResponse.GetResponseStream();
        int byteCount = Convert.ToInt32(httpWebResponse.ContentLength);
        byte[] Buffer1 = new byte[byteCount];
        using (BinaryReader reader = new BinaryReader(stream))
        {
            Buffer1 = reader.ReadBytes(byteCount);
        }
        Response.Clear();
        Response.ClearHeaders();
        // set the content type to PDF 
        Response.ContentType = "application/pdf";
        Response.AddHeader("Content-Disposition", "attachment;filename=Filename.pdf");
        Response.Buffer = true;
        Response.BinaryWrite(Buffer1);
        Response.Flush();
       // Response.End();
    }
}

Я полагаю, что это уже упоминалось в той или иной форме, но я попытаюсь изложить это своими словами.

Вместо этого:

/bar/sessions/958d8a22-0/views/1493881172/export?format=application/pdf&no-attachment=true

Я использую это:

/bar/sessions/958d8a22-0/views/1493881172/NameThatIWantPDFToBe.pdf?GeneratePDF=1

Вместо того, чтобы "экспортировать" обработку запроса, когда приходит запрос, я просматриваю URL для GeneratePDF=1.Если я найден, я запускаю любой код, который был запущен в "экспорте", вместо того, чтобы позволять моей системе пытаться искать и отправлять PDF-файл в указанном местоположении /bar/sessions/958d8a22-0/views/1493881172/NameThatIWantPDFToBe.pdf.Если GeneratePDF не найден в URL-адресе, я просто передаю запрошенный файл.(обратите внимание, что я не могу просто перенаправить на запрошенный файл - иначе я оказался бы в бесконечном цикле)

У вас всегда может быть две ссылки.Один, который открывает документ внутри браузера, а другой - для его загрузки (используя неправильный тип содержимого).Это то, что делает Gmail.

Для тех, кто все еще смотрит на это, я использовал найденное решение здесь и это сработало чудесно.Спасибо, Фабрицио!

Способ, которым я решил это (с помощью PHP), заключается в следующем:

Предположим, ваш URL-адрес следующий SomeScript.php?id=ID&data=DATA и файл, который вы хотите использовать, это TEST.pdf.

Измените URL-адрес на SomeScript.php/id/ID/data/DATA/EXT/TEST.pdf.

Важно, чтобы последним параметром было имя файла, которое вы хотите использовать Adobe ("EXT" может означать что угодно).Кстати, убедитесь, что в приведенной выше строке нет специальных символов.

Теперь, на вершине SomeScript.php, добавить:

$_REQUEST = MakeFriendlyURI( $_SERVER['PHP\_SELF'], $_SERVER['SCRIPT_FILENAME']);

Затем добавьте эту функцию в SomeScript.php (или ваша библиотека функций):

function MakeFriendlyURI($URI, $ScriptName) {

/* Need to remove everything up to the script name */
$MyName = '/^.*'.preg_quote(basename($ScriptName)."/", '/').'/';
$Str = preg_replace($MyName,'',$URI);
$RequestArray = array();

/* Breaks down like this
      0      1     2     3     4     5
    PARAM1/VAL1/PARAM2/VAL2/PARAM3/VAL3
*/

$tmp = explode('/',$Str);   
/* Ok so build an associative array with Key->value
   This way it can be returned back to $_REQUEST or $_GET
 */
for ($i=0;$i < count($tmp); $i = $i+2){
    $RequestArray[$tmp[$i]] = $tmp[$i+1];
}
return $RequestArray;       
}//EO MakeFriendlyURI

Сейчас $_REQUEST (или $_GET если вы предпочитаете) доступен как обычный $_REQUEST['id'], $_REQUEST['data'], и т.д.

И Adobe будет использовать желаемое вами имя файла в качестве сохраняемого по умолчанию имени или информации по электронной почте, когда вы отправите его встроенным.

Я был перенаправлен сюда, потому что у меня такая же проблема.Я также попробовал обходной путь Троя Ховарда, но, похоже, он не работает.

Подход, который я применил в этом случае, заключается в ТОМ, чтобы БОЛЬШЕ НЕ использовать объект ответа для записи файла "на лету".Поскольку PDF-файл уже существует на сервере, я перенаправил свою страницу, указывающую на этот PDF-файл.Отлично работает.

http://forums.asp.net/t/143631.aspx

Я надеюсь, что мое расплывчатое объяснение натолкнуло вас на какую-то идею.

Кредиты для Вивек.


Nginx

location /file.pdf
{
    # more_set_headers "Content-Type: application/pdf; name=save_as_file.pdf";
    add_header Content-Disposition "inline; filename=save_as_file.pdf";
    alias /var/www/file.pdf;
}

Проверьте с помощью

curl -I https://example.com/file.pdf

Firefox 62.0b5 (64-разрядный):ОК.

Chrome 67.0.3396.99 (64-разрядная версия):ОК.

IE 11:Без комментариев.

Попробуйте это, если ваш исполняемый файл "get.cgi"

http://server ,org/get.cgi/filename.pdf?файл=filename.pdf

Да, это полное безумие.На сервере нет файла с именем "filename.pdf", вообще есть каталог под исполняемым файлом get.cgi.

Но, кажется, это работает.Сервер игнорирует filename.pdf, а программа чтения PDF игнорирует "get.cgi".

Dan

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top