문제

내 앱은 사용자 소비를 위해 PDF를 생성합니다. "Content-Disposition"HTTP 헤더가 언급 된대로 설정됩니다. 여기. 이것은 "inline; filename = foo.pdf"로 설정되며, Acrobat은 PDF를 저장할 때 "foo.pdf"를 파일 이름으로 제공하기에 충분해야합니다.

그러나 브라우저가 매달린 Acrobat에서 "저장"버튼을 클릭하면 저장할 기본 이름은 파일 이름이 아니라 슬래시가있는 URL이 밑줄로 변경되었습니다. 거대하고 못 생겼습니다. Adobe 에서이 기본 파일 이름에 영향을 줄 수있는 방법이 있습니까?

URL에는 쿼리 문자열이 있으며 이는 협상 할 수 없습니다. 이것은 중요 할 수 있지만 URL 끝에 "& foo =/title.pdf"를 추가하는 것은 기본 파일 이름에 영향을 미치지 않습니다.

업데이트 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 Save는 Filename으로 변환됩니다.

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

업데이트 3 : Julian Reschke는이 경우에 실제 통찰력과 엄격함을 제공합니다. 그의 대답을 발전 시키십시오. 이것은 FF에서 깨진 것 같습니다.https://bugzilla.mozilla.org/show_bug.cgi?id=433613) 그리고 즉, 오페라, 사파리 및 크롬에서 일합니다. http://greenbytes.de/tech/tc2231/#inlwithasciifilenamepdf

도움이 되었습니까?

해결책

문제의 일부는 관련이 있다는 것입니다 RFC 2183 실제로 "인라인"과 파일 이름의 처분 유형으로 무엇을 해야하는지 명시하지 않습니다.

또한, 내가 알 수있는 한, 실제로 유형의 파일 이름을 사용하는 유일한 UA는 Firefox입니다. 테스트 케이스).

마지막으로, 플러그인 API가 실제로 해당 정보를 사용할 수있게한다는 것은 분명하지 않습니다 (API에 익숙한 일부는 정교해질 수 있음).

즉, 나는이 질문에 대한 포인터를 Adobe 사람에게 보냈습니다. 어쩌면 올바른 사람들이 보게 될 것입니다.

관련 : http in의 내용화를 명확히하려는 시도를 참조하십시오. Draft-Reschke-RFC2183-in-HTTP - 이것은 조기 진행중인 작업입니다. 피드백은 감사합니다.

업데이트 : 추가했습니다 테스트 케이스, 플러그인 API가 이들에 대한 액세스를 제공하지만 Acrobat Reader 플러그인 (Acrobat Reader Plugin)이 응답 헤더 (Firefox)를 사용하지 않는 것으로 보입니다.

다른 팁

설정 파일 이름 안에 컨텐츠 타입 또한. 이것은 문제를 해결해야합니다.

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

컨텐츠 공모 헤더를 설정 한 후에는 컨텐츠 길이 헤더를 추가 한 다음 BinaryWrite를 사용하여 PDF를 스트리밍하십시오.

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

당신처럼, 나는 이것을 시도하고 노력했다. 마침내 나는이 아이디어를 포기하고 해결 방법을 선택했다.

ASP.NET MVC 프레임 워크를 사용하고 있으므로 해당 컨트롤러/작업에 대한 경로를 수정하여 제공된 PDF 파일이 URI의 위치 부분의 마지막 부분 (쿼리 문자열 이전)인지 확인하고 모든 것을 전달합니다. 쿼리 문자열에서.

예 :

Old Uri :

http : // server/app/report/showpdf? param1 = foo¶m2 = bar & filename = myreport.pdf

새로운 URI :

http : //server/app/report/showpdf/myreport.pdf? param1 = foo¶m2 = bar

결과 헤더는 설명한 내용과 똑같이 보입니다 (콘텐츠 유형은 Application/PDF, 배치는 인라인이며 파일 이름은 헤더의 일부입니다). Acrobat은 브라우저 창 (저장 대화 상자 없음)에 표시되며 사용자가 Acrobat 저장 버튼을 클릭하는 경우 자동 인구가있는 파일 이름은 보고서 파일 이름입니다.

몇 가지 고려 사항 :

파일 이름이 괜찮아 보이려면 탈출 된 캐릭터 (예 : 공백 등)가 없어야합니다. 내 파일 이름은이 경우 자동으로 생성되었으며 이전에는 공백이 있었으며 결과 저장 대화 상자 파일 이름에서 '%20'으로 표시되었습니다. 방금 공간을 밑줄로 교체했습니다.

이것은 가장 좋은 솔루션이 아니지만 작동합니다. 또한 원래 URI의 일부를 만들기 위해 파일 이름을 사용할 수 있어야하며 프로그램의 워크 플로를 엉망으로 만들 수 있습니다. PDF를 생성하는 서버 측 호출 중에 데이터베이스에서 현재 생성 또는 검색중인 경우 양식 제출의 일부로 파일 이름을 JavaScript로 생성하는 코드를 이동해야하거나 데이터베이스에서 오는 경우 빠른 ajax 호출 PDF가 인쇄 된 URL을 구축 할 때 파일 이름을 얻습니다.

양식의 사용자 입력에서 파일 이름을 가져 오면 이스케이프 문자를 포함하지 않도록 검증되어 사용자를 괴롭 힙니다.

도움이되기를 바랍니다.

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에서 작동하며 Default Saveas Filename은 지금입니다. 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을 사용하는 경우 페이지 (URL) 파일 이름을 통해 PDF 파일 이름을 제어 할 수 있습니다. 다른 사용자가 쓴 것처럼 Acrobat은 약간 s입니다 ... "저장"버튼을 누를 때 PDF 파일 이름을 선택할 때 : 페이지 이름을 가져 가고 확장자를 제거하고 ".pdf"를 추가합니다. so /foo/bar/getmypdf.aspx는 getmypdf.pdf를 제공합니다.

내가 찾은 유일한 솔루션은 ASP.NET 핸들러를 통해 "동적"페이지 이름을 관리하는 것입니다.

  • ihttphandler를 구현하는 클래스를 만듭니다
  • web.config에 클래스에 핸들러를 매핑하십시오

Mapping1 : 모든 페이지에는 공통 Radix가 있습니다 (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. 스트림 길이를 기준으로 올바른 바이트 길이의 스트림에서 바이트 arrrary를 읽으십시오.
  3. 올바른 contentType를 설정하십시오

다음은 읽기 스트림 및 파일 다운로드 코드 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

"내보내기"를 처리하는 대신 요청이 들어 오면 generatepdf = 1에 대한 URL을 살펴 봅니다. 발견되면 시스템이 위치에서 PDF를 검색하고 제공하려고 시도하는 대신 "Export"에서 실행중인 코드를 실행합니다. /bar/sessions/958d8a22-0/views/1493881172/NameThatIWantPDFToBe.pdf. URL에서 GeneratePDF가 발견되지 않으면 요청 된 파일을 간단히 전송합니다. (요청 된 파일로 간단히 리디렉션 할 수는 없습니다. 그렇지 않으면 끝없는 루프가 끝납니다).

You could always have two links. One that opens the document inside the browser, and another to download it (using an incorrect content type). This is what Gmail does.

For anyone still looking at this, I used the solution found here and it worked wonderfully. Thanks Fabrizio!

The way I solved this (with PHP) is as follows:

Suppose your URL is SomeScript.php?id=ID&data=DATA and the file you want to use is TEST.pdf.

Change the URL to SomeScript.php/id/ID/data/DATA/EXT/TEST.pdf.

It's important that the last parameter is the file name you want Adobe to use (the 'EXT' can be about anything). Make sure there are no special chars in the above string, BTW.

Now, at the top of SomeScript.php, add:

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

Then add this function to SomeScript.php (or your function library):

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

Now $_REQUEST (or $_GET if you prefer) is accessed like normal $_REQUEST['id'], $_REQUEST['data'], etc.

And Adobe will use your desired file name as the default save as or email info when you send it inline.

I was redirected here because i have the same problem. I also tried Troy Howard's workaround but it is doesn't seem to work.

The approach I did on this one is to NO LONGER use response object to write the file on the fly. Since the PDF is already existing on the server, what i did was to redirect my page pointing to that PDF file. Works great.

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

I hope my vague explanation gave you an idea.

Credits to Vivek.


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;
}

Check with

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

Firefox 62.0b5 (64-bit): OK.

Chrome 67.0.3396.99 (64-Bit): OK.

IE 11: No comment.

Try this, if your executable is "get.cgi"

http://server,org/get.cgi/filename.pdf?file=filename.pdf

Yes, it's completely insane. There is no file called "filename.pdf" on the server, there is directory at all under the executable get.cgi.

But it seems to work. The server ignores the filename.pdf and the pdf reader ignores the "get.cgi"

Dan

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top