我有一些大尺寸的PDF目录在我的网站上,我需要链接这些下载。当我在谷歌上搜索时,我发现下面有这样一件事。它应该打开“另存为…”弹出链接点击…

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

但它不工作:/当我链接到一个文件如下,它只是链接到文件,并试图打开文件。

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

更新(根据以下答案):

据我所知,没有100%可靠的跨浏览器解决方案。也许最好的方法是使用下面列出的web服务之一,并提供下载链接…

http://box.net/ http://droplr.com/ http://getcloudapp.com/


当前回答

服务器端解决方案更具兼容性,直到“download”属性在所有浏览器中实现。

一个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()

其他回答

我刚刚用了这个,但我不知道它是否适用于所有浏览器。

它适用于Firefox:

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

我只是有一个非常类似的问题,我需要在一个ZIP文件中创建下载链接。

我首先尝试创建一个临时文件,然后提供一个到临时文件的链接,但我发现一些浏览器只会显示内容(一个CSV Excel文件)而不提供下载。最终我通过使用servlet找到了解决方案。它可以在Tomcat和GlassFish上运行,我还在Internet Explorer 10和Chrome上试用了它。

servlet将ZIP文件的完整路径名和应该下载的ZIP文件中的文件名作为输入。

在我的JSP文件中,我有一个表,显示zip中的所有文件,其中的链接说:onclick='download?邮政= < % = zip % > csv = < % = % > csv '

servlet代码在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中设置servlet。

服务器端解决方案更具兼容性,直到“download”属性在所有浏览器中实现。

一个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()

这是旧的帖子,但这是一个我的解决方案在JavaScript使用jQuery库。

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

您只需要在<a>标记中使用类force-download,就会自动强制下载。您也可以将它添加到父div,并将拾取其中的所有链接。

例子:

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

这对于WordPress和任何其他系统或自定义网站来说都是很棒的。

Chrome 91有一个新的变化,它支持Chrome 86-90和91+。 下面的语法将使其发生。

const fileHandle = await self.showSaveFilePicker({
   suggestedName: 'Untitled Text.txt',
   types: [{
      description: 'Text documents',
      accept: {
        'text/plain': ['.txt'],
      },
   }],
});

点击此处阅读更多信息:

https://developer.chrome.com/blog/new-in-chrome-91/

**另一个解决方案,你可以把它作为一个blob,然后使用savas **

const blob = fetch("some-url-here").then(data => data.blob());
saveAs(blob, "filename.txt")