HTML에서 PDF의 텍스트 링크를 클릭하면 "다른 이름으로 저장 ..."팝업이 열립니다.


173

내 웹 사이트에 큰 크기의 PDF 카탈로그가 있으며 다운로드로 링크해야합니다. 내가봤을 때 아래에 언급 된 것을 발견했습니다. 링크 클릭시 " 다른 이름으로 저장 ... "팝업 이 열립니다 ...

 <head>
    <meta name="content-disposition" content="inline; filename=filename.pdf">
    ...

그러나 그것은 작동하지 않습니다 : / 아래처럼 파일에 링크하면 파일에 연결되어 파일을 열려고합니다.

    <a href="filename.pdf" title="Filie Name">File name</a>

업데이트 (아래 답변에 따라) :

보시다시피 100 % 신뢰할 수있는 크로스 브라우저 솔루션은 없습니다. 아마도 가장 좋은 방법은 아래에 나열된 웹 서비스 중 하나를 사용하고 다운로드 링크를 제공하는 것입니다 ...


1
pdf 파일의 mimetype을 제공하지 마십시오.
bhups

업데이트 된 솔루션 인 artmania를 시도했지만 Safari에서 겪었던 것과 동일한 문제가 발생했습니다. 브라우저 창에서 PDF 모양을 볼 수 있으며 맨 아래에있는 "미리보기"또는 "다운로드"탭을 클릭해야만 필사적으로 필요한 검색 기능이 제공됩니다.
heathwaller


답변:


267

링크를 클릭 한 후 브라우저가 파일을 저장 하도록 강제 :

<a href="path/to/file" download>Click here to download</a>

17
이 의견을 제출할 당시 download속성은 Chrome, Firefox 및 Opera로 제한됩니다. 최신 버전의 IE 및 Safari에서도 지원하지 않습니다. 향후 지원 : caniuse.com/#feat=download 확인 !
Sygmoral

Netbeans 오류 검사에 대해 불평하지만 제대로 작동하는 것 같습니다. 다음과 같이 새 파일의 예비 이름을 지정할 수 있습니다. download = "myFile.txt"
Yster

1
이것은 주석을 작성할 때 Edge에서 작동하며 PDF 뷰어에서 Edge의 매우 열악한 시도에서 하이퍼 링크 된 PDF가 열리는 것을 막을 수있는 유일한 방법 인 것 같습니다.

이 의견을 제출할 당시 Chrome, Opera, Edge, Mozilla에서 테스트했습니다. 모든 최신. Mozilla를 제외한 모든 작업을 수행하고 있습니다.
SI

7
caniuse.com/#feat=download에 언급 된 것처럼 동일한 출처 링크에서만 작동합니다 . 귀하의 링크가 교차 출처 인 경우, 현재로서는 유일한 답변은 많은 답변에서 알 수 있듯이 응답 유형을 "application / octet-stream"으로 강제하는 것입니다. 서버에 액세스 할 수없는 경우 프록시를 시도하고 응답 헤더를 수동으로 설정할 수 있습니다.
장 밥 티스트

80
<a href="file link" download target="_blank">Click here to download</a>

Firefox 및 Chrome에서 작동합니다.


2
2013 년 Ayush Gupta의 현재 최고 답변과 정확히 동일 target="_blank"합니다. 그래도 지원되지 않는 브라우저에서 약간 더 유용하게 사용할 수 있습니다 (PDF는 현재 페이지를 덮어 쓰지 않고 새 창 / 탭에서 열립니다).
Sygmoral

3
나를 위해, 다운로드를 제대로 실행하지 못했기 target="_blank"때문에 필요 download했습니다 (Chrome)
casraf

2
download속성에 문자열을 제공하면 파일 이름으로 사용됩니다. 나는 항상 사용자 스크립트에서 사용하고 있습니다.
weaknespase

34

메타 태그는이 결과를 얻을 수있는 확실한 방법이 아닙니다. 일반적으로이 작업을 수행해서는 안됩니다. 사용자가 제공하는 컨텐츠와 관련하여 결정하는 것은 사용자 / 사용자 에이전트의 책임입니다. 사용자는 원하는 경우 언제든지 브라우저가 파일을 다운로드하도록 할 수 있습니다.

여전히 브라우저가 파일을 다운로드하도록하려면 HTTP 헤더를 직접 수정하십시오. 다음은 PHP 코드 예입니다.

$path = "path/to/file.pdf";
$filename = "file.pdf";
header('Content-Transfer-Encoding: binary');  // For Gecko browsers mainly
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', filemtime($path)) . ' GMT');
header('Accept-Ranges: bytes');  // Allow support for download resume
header('Content-Length: ' . filesize($path));  // File size
header('Content-Encoding: none');
header('Content-Type: application/pdf');  // Change the mime type if the file is not PDF
header('Content-Disposition: attachment; filename=' . $filename);  // Make the browser display the Save As dialog
readfile($path);  // This is necessary in order to get it to actually download the file, otherwise it will be 0Kb

이것은 HTTP 프로토콜의 확장 일뿐입니다. 어쨌든 일부 브라우저는 무시할 수 있습니다.


4
실제로 나는 이것이 널리 구현되어 있다고 생각합니다.
Matthew Wilson

이것은 최고의 솔루션이며 번거롭지 않고 작동합니다. 이 방법을 사용하여 모든 파일 형식을 직접 다운로드 할 수 있습니다. +1
casraf

3
HTTP에는 콘텐츠 전송 인코딩이 없습니다. 콘텐츠 인코딩 : 쓸모없는 것은 없습니다.
Julian Reschke

IF 파일이 외부 서버 / 도메인에서 온 것이라는 답변에주의하십시오.
T.Todua

파일이 커지면 (이 경우 80MB 이상) 특정 서버 에서이 코드 또는 유사한 코드가 실패했다고 덧붙이고 싶습니다. 사용하는 ob_end_flush()것도 도움이되지 않았습니다.
Hendrik

22

나는이 같은 문제가 있었고 지금까지 잘 작동하는 솔루션을 찾았습니다. .htaccess파일에 다음 코드를 넣습니다 .

<FilesMatch "\.(?i:pdf)$">
  ForceType application/octet-stream
  Header set Content-Disposition attachment
</FilesMatch>

그것은 온 힘 브라우저에 표시하는 대신 다운로드 할 수있는 파일 .


4
다운로드를위한 특정 문서 디렉토리가 있었기 때문에 잘 작동했습니다. 형식을 그대로 유지하기 위해 ForceType을 생략했습니다. 또한 대소 문자를 구분하지 않아도됩니다. 광산은 이미 대소 문자를 구분하지 않는 것 같습니다. 이전 / 새 Office 확장에 대한 optional-x를 포함하여 몇 가지 추가 유형을 추가했습니다.<FilesMatch "\.(pdf|xlsx?|docx?)$">
goodeye

이것은 OSX Safari에서도 훌륭하게 작동했습니다. 다른 답변 (한 의견자가 지적한대로 허용되는 답변 포함)은 주어진 HTML 기능을 지원하는 특정 브라우저로 제한됩니다. 이것은 서버 구성 파일에 대한 높은 수준의 액세스가 필요하지만 보드 전체에서 작동했기 때문에 나에게 이상적입니다.
브라이트

apache.conf 파일에 바로 넣을 수도 있습니다. 더 많은 리소스가 필요하므로 .htaccess를 사용하지 않습니다.
Michael Fever

htaccess 파일을 읽을 수 없기 때문에 Windows에서 호스팅하는 웹 사이트는 어떻게 이것을 구현합니까?
PoloHoleSet

9

Firefox에 대한 매우 간단한 솔루션을 찾았습니다 (직접 href가 아닌 상대와 만 작동) : add type="application/octet-stream":

<a href="./file.pdf" id='example' type="application/octet-stream">Example</a>

1
Chrome OS에서는 @Martin Chrome, Linux에서는 Firefox 파일이 작동하려면 로컬 파일이어야합니다. 내 href는 클라우드 저장소에 대한 URL이었습니다.
ttfreeman

7

이 줄을 .htaccess 파일에 추가하십시오.

AddType application/octet-stream .pdf

브라우저 독립적이므로 작동하기를 바랍니다.


왜 이것이 다운 보트
Nathan Hornby

사람들은 무료 호스팅 사이트에서 서버의 핵심 기능을 수정 한 다음 작동하지 않기 때문에 다운 보트를 시도합니다. 다른 모든 솔루션은 이것을 대체하는 "핵"이기 때문에 경고가 있습니다.
버려진 카트

문제에 대한 잘못된 해결책이기 때문에 그것을 내리고 있습니다. 리소스 유형을 혼란스럽게하는 것은 나쁜 생각입니다.
브래드

@NathanHornby-다운 다운하지는 않았지만 .htaccess를 사용하지 않기 때문에 Windows 호스팅 사이트에서는 작동하지 않습니다.
PoloHoleSet

공감하지는 않았지만이 솔루션은 해당 접미사의 모든 파일에 맹목적으로 영향을 미칩니다. 그것은 무차별 적이므로 모든 경우에 적절하지는 않습니다.
JBH

6

일부 브라우저 설정 또는 플러그인은 간단한 웹 페이지와 같은 창에서 PDF를 직접 열기 때문에 일반적으로 발생합니다.

다음이 도움이 될 수 있습니다. 몇 년 전에 PHP에서 해냈습니다. 그러나 현재 나는 그 플랫폼에서 일하고 있지 않습니다.

<?php
    if (isset($_GET['file'])) {
        $file = $_GET['file'];
        if (file_exists($file) && is_readable($file) && preg_match('/\.pdf$/',$file)) {
            header('Content-type: application/pdf');
            header("Content-Disposition: attachment; filename=\"$file\"");
            readfile($file);
        }
    }
    else {
        header("HTTP/1.0 404 Not Found");
        echo "<h1>Error 404: File Not Found: <br /><em>$file</em></h1>";
    }
?>

위의 내용을 download.php 로 저장하십시오 .

이 작은 스 니펫을 서버의 어딘가에 PHP 파일로 저장하면 직접 표시하지 않고 브라우저에서 파일을 다운로드 할 수 있습니다. PDF 이외의 파일을 제공하려면 5 행을 제거하거나 편집하십시오.

다음과 같이 사용할 수 있습니다.

HTML 파일에 다음 링크를 추가하십시오.

<a href="download.php?file=my_pdf_file.pdf">Download the cool PDF.</a>

참조 : 이 블로그


7
이것은 서버의 모든 단일 파일을주의를 기울이는 사람에게 제공 할 수있는 좋은 방법 인 것 같습니다. download.php?file=database_password_file.php예를 들어.
pbarney

5

아래 코드를 .htaccess파일 에 넣으십시오 .

AddType application/octet-stream .csv
AddType application/octet-stream .xls
AddType application/octet-stream .doc
AddType application/octet-stream .avi
AddType application/octet-stream .mpg
AddType application/octet-stream .mov
AddType application/octet-stream .pdf

또는 JavaScript로 속일 수도 있습니다

element.setAttribute( 'download', whatever_string_you_want);

1
이것은 웹 서버가 Apache 라고 가정하지 않습니까?
Peter Mortensen

5

방금 이것을 사용했지만 모든 브라우저에서 작동하는지 모르겠습니다.

Firefox에서 작동합니다.

<a href="myfile.pdf" download>Click to Download</a>

1
그것은 초기 답변 에서 더 많은 배경 정보와 함께 제안 됩니다.
usr2564301

4

외부 다운로드 사이트를 사용하거나 헤더를 수정하지 않고 이것을 달성 하는 정말 간단한 방법은 내부에 PDF로 ZIP 파일을 만들고 ZIP 파일에 직접 연결하는 것입니다. 이렇게하면 항상 저장 / 열기 대화 상자가 트리거되며 사람들이 여전히 .zip과 관련된 프로그램이 시작된 PDF 창을 두 번 클릭하기 쉽습니다.

BTW 큰 질문은 대부분의 브라우저 내장 PDF 플러그인이 아무것도 표시하는 데 너무 오래 걸리기 때문에 (그리고 PDF 가로 드되는 동안 브라우저를 종종 멈추게 함) 대답을 찾고있었습니다.


31
끔찍한 사용성. 많은 최종 사용자는 zip 파일로 수행 할 작업을 모릅니다.
CodeWarrior

1
때로는 간단한 solutioans가 최고의 솔루션입니다!
elrado

1
좋은 해결책이 아닙니다. Firefox와 ZIP 파일에 문제가 있습니다. 어떻게해야합니까? 파일을 ZIP? 이 경우 HTTP 헤더를 수정하는 것이 해결책 일 수는 있지만 액세스 할 수는 없습니다.
Arnaud Weil

2

"다운로드"속성이 모든 브라우저에서 구현 될 때까지 서버 측 솔루션이 더 호환됩니다.

하나의 Python 예제는 파일 저장소에 대한 사용자 정의 HTTP 요청 핸들러 일 수 있습니다. 파일 저장소를 가리키는 링크는 다음과 같이 생성됩니다.

http://www.myfilestore.com/filestore/13/130787e71/download_as/desiredName.pdf

코드는 다음과 같습니다.

class HTTPFilestoreHandler(SimpleHTTPRequestHandler):

    def __init__(self, fs_path, *args):
        self.fs_path = fs_path                          # Filestore path
        SimpleHTTPRequestHandler.__init__(self, *args)

    def send_head(self):
        # Overwrite SimpleHTTPRequestHandler.send_head to force download name
        path = self.path
        get_index = (path == '/')
        self.log_message("path: %s" % path)
        if '/download_as/' in path:
            p_parts = path.split('/download_as/')
            assert len(p_parts) == 2, 'Bad download link:' + path
            path, download_as = p_parts
        path = self.translate_path(path )
        f = None
        if os.path.isdir(path):
            if not self.path.endswith('/'):
                # Redirect browser - doing basically what Apache does
                self.send_response(301)
                self.send_header("Location", self.path + "/")
                self.end_headers()
                return None
            else:
                return self.list_directory(path)
        ctype = self.guess_type(path)
        try:
            f = open(path, 'rb')
        except IOError:
            self.send_error(404, "File not found")
            return None
        self.send_response(200)
        self.send_header("Content-type", ctype)
        fs = os.fstat(f.fileno())
        self.send_header("Expires", '0')
        self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
        self.send_header("Cache-Control", 'must-revalidate, post-check=0, pre-check=0')
        self.send_header("Content-Transfer-Encoding", 'binary')
        if download_as:
            self.send_header("Content-Disposition", 'attachment; filename="%s"' % download_as)
        self.send_header("Content-Length", str(fs[6]))
        self.send_header("Connection", 'close')
        self.end_headers()
        return f


class HTTPFilestoreServer:

    def __init__(self, fs_path, server_address):
        def handler(*args):
            newHandler = HTTPFilestoreHandler(fs_path, *args)
            newHandler.protocol_version = "HTTP/1.0"
        self.server = BaseHTTPServer.HTTPServer(server_address, handler)

    def serve_forever(self, *args):
        self.server.serve_forever(*args)


def start_server(fs_path, ip_address, port):
    server_address = (ip_address, port)
    httpd = HTTPFilestoreServer(fs_path, server_address)

    sa = httpd.server.socket.getsockname()
    print "Serving HTTP on", sa[0], "port", sa[1], "..."
    httpd.serve_forever()

2

페이지에서 단일 링크를 강제로 다운로드해야하는 경우 href-link에서 HTML5 다운로드 속성을 사용하는 것이 가장 쉬운 방법입니다.

참조 : http://davidwalsh.name/download-attribute

이를 통해 사용자가 다운로드 할 파일의 이름을 바꾸고 동시에 강제로 다운로드 할 수 있습니다.

이것이 좋은 습관인지 아닌지에 대한 논쟁이 있었지만 제 경우에는 PDF 파일에 대한 뷰어가 내장되어 있으며 뷰어는 다운로드 링크를 제공하지 않으므로 별도로 제공해야합니다. 여기서는 사용자가 웹 브라우저에서 PDF를 열지 못하게하여 혼란 스러울 수 있습니다.

대화 상자로 저장을 열 필요는 없지만 미리 설정된 다운로드 대상으로 바로 연결되는 링크를 다운로드합니다. 물론 다른 사람을 위해 사이트를 운영하고 있고 링크에 수동으로 속성을 작성해야하는 경우는 좋지 않습니다. 그러나 속성을 링크에 가져올 수있는 방법이 있다면 이는 가벼운 해결책 일 수 있습니다.


1

이것은 오래된 게시물이지만 jQuery 라이브러리를 사용하는 JavaScript의 솔루션입니다.

<script>
(function($){
    var download = [];
    $('a.force-download, .force-download a').each(function(){
        // Collect info
        var $this = $(this),
            $href = $this.attr('href'),
            $split = $href.split('/'),
            $name = document.title.replace(/[\W_]/gi, '-').replace(/-{2,}/g, '-'); // get title and clean it for the URL

        // Get filename from URL
        if($split[($split.length-1)])
        {
            $tmp = $split[($split.length-1)];
            $tmp = $tmp.split('.');
            $name = $tmp[0].replace(/[\W_]/gi, '-').replace(/-{2,}/g, '-');
        }

        // If name already exists, put timestamp there
        if($.inArray($name, download) > -1)
        {
            $name = $name + '-' + Date.now().replace(/[\W]/gi, '-');
        }

        $(this).attr("download", $name);
        download.push($name);
    });
}(jQuery || window.jQuery))
</script>

태그 force-download내에서 클래스를 사용해야 <a>하며 다운로드 자동 분석이 필요합니다. 또한 부모에 추가 할 수 있으며 그 div안에있는 모든 링크를 가져옵니다.

예:

<a href="/some/good/url/Post-Injection_Post-Surgery_Instructions.pdf" class="force-download" target="_blank">Download PDF</a>

이것은 WordPress 및 기타 시스템 또는 사용자 정의 웹 사이트에 유용합니다.


0

HTML 코드에서 파일 이름 뒤에 ?forcedownload=1

이것이 대화 상자를 저장하거나 다운로드 할 수있는 가장 간단한 방법이었습니다.


0

브라우저 내에 PDF 파일을 여는 방법을 알고있는 플러그인이 있으면 직접 열립니다. 이미지 및 HTML 컨텐츠의 경우와 같습니다.

따라서 대안은 MIME 유형을 응답으로 보내지 않는 것입니다. 이런 식으로 브라우저는 어떤 플러그인을 열어야하는지 알 수 없습니다. 따라서 저장 / 열기 대화 상자가 나타납니다.


MIME 형식을 보내는 서버이므로 PDF 파일에 직접 연결할 때 헤더를 변경할 수 없으므로 달성하기가 어렵습니다.
Karel Petranek

0

ZIP 파일 내의 파일에 대한 다운로드 링크를 작성해야하는 추가 된 문제와 비슷한 문제가 발생했습니다.

먼저 임시 파일을 만든 다음 임시 파일에 대한 링크를 제공했지만 일부 브라우저는 다운로드를 제공하는 대신 내용 (CSV Excel 파일) 만 표시한다는 것을 알았습니다. 결국 서블릿을 사용하여 솔루션을 찾았습니다. Tomcat과 GlassFish에서 모두 작동하며 Internet Explorer 10 및 Chrome에서 시도했습니다.

서블릿은 ZIP 파일의 전체 경로 이름과 다운로드해야하는 zip 내부 파일 이름을 입력으로 사용합니다.

내 JSP 파일에는 zip 내부의 모든 파일을 표시하는 링크가있는 표가 있습니다. onclick='download?zip=<%=zip%>&csv=<%=csv%>'

서블릿 코드는 download.java에 있습니다.

package myServlet;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.zip.*;
import java.util.*;

// Extend HttpServlet class
public class download extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException
    {
        PrintWriter out = response.getWriter(); // now we can write to the client

        String filename = request.getParameter("csv");
        String zipfile = request.getParameter("zip");

        String aLine = "";

        response.setContentType("application/x-download");
        response.setHeader( "Content-Disposition", "attachment; filename=" + filename); // Force 'save-as'
        ZipFile zip = new ZipFile(zipfile);
        for (Enumeration e = zip.entries(); e.hasMoreElements();) {
            ZipEntry entry = (ZipEntry) e.nextElement();
            if(entry.toString().equals(filename)) {
                InputStream is = zip.getInputStream(entry);
                BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"), 65536);
                while ((aLine = br.readLine()) != null) {
                    out.println(aLine);
                }
                is.close();
                break;
            }
        }
    }
}

Tomcat을 컴파일하려면 tomcat \ lib \ servlet-api.jar 또는 GlassFish를 포함하는 클래스 경로가 필요합니다. glassfish \ lib \ j2ee.jar

그러나 어느 쪽이든 둘 다 작동합니다. 서블릿을에 설정해야합니다 web.xml.


0

응답 헤더 추가 Content-Disposition : attachment; 그 뒤에 파일 이름이옵니다. Meta Content-Disposition; Inline; 같은 창에서 문서가 열립니다

자바에서는 다음과 같이 설정됩니다

response.setHeader("Content-Disposition", "attachment;filename=test.jpg");

-2

큰 PDF 파일을 사용하면 브라우저가 중단됩니다. Mozilla에서 메뉴 도구옵션응용 프로그램 을 선택한 다음 컨텐츠 유형 Adobe Acrobat 문서 옆에 있습니다. 작업 드롭 다운에서 항상 묻기를 선택 합니다.

이것은 나를 위해 작동하지 않았으므로 효과가 있었던 것은 다음과 같습니다.

메뉴 도구 * → 애드온Adobe Acrobat (Firefox 용 Adobe PDF 플러그인) → 비활성화. 이제 전자 책을 다운로드 할 수 있습니다!


2
질문을 읽었습니까? 이것은 크로스 브라우저 답변이 아닙니다
Mark

1
@mark 또한 웹 사이트 소유자가 아닌 PDF를 강제로 다운로드하라는 메시지를 표시합니다.
Nathan Hornby
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.