强制打开“另存为”;弹出打开在文本链接点击PDF在HTML

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

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

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

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

更新(根据以下答案):

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

  • < a href = " http://box.net/ " rel = " noreferrer > http://box.net/ < / >
  • < a href = " http://droplr.com/ " rel = " noreferrer > http://droplr.com/ < / >
  • http://getcloudapp.com/
449846 次浏览

如果你在浏览器中有一个插件知道如何打开PDF文件,它会直接打开。比如图像和HTML内容。

因此,另一种方法是在响应中不发送MIME类型。这样,浏览器就永远不会知道哪个插件应该打开它。因此它会给你一个保存/开放对话框。

通常会发生这种情况,因为一些浏览器设置或插件会直接在同一个窗口中打开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>

引用自:这个博客

元标签并不是实现这一结果的可靠方法。一般来说,你甚至不应该这样做——应该由用户/用户代理来决定如何处理你提供的内容。如果用户愿意,总是可以强制浏览器下载文件。

如果您仍然希望强制浏览器下载文件,请直接修改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协议的扩展;有些浏览器可能会忽略它。

一个真的简单的方法来实现这一点,不使用外部下载网站或修改标题等,就是简单地创建一个ZIP文件,里面有PDF,并直接链接到ZIP文件。这总是会触发保存/打开对话框,人们仍然很容易双击PDF窗口,与.zip相关的程序被启动。

顺便说一句,这是个好问题,我也在寻找答案,因为大多数浏览器内置的PDF插件需要很长时间才能显示任何东西(并且在PDF加载时经常会挂起浏览器)。

对于大的PDF文件,浏览器挂起。 在Mozilla中,菜单工具选项应用程序,然后在内容类型旁边的adobeacrobat文档。 在Action下拉菜单中,选择总是问.

这对我没用,所以有用的是:

菜单工具*→附加组件Adobe Acrobat (Adobe PDF插件for Firefox)→DISABLE。 现在我可以下载电子书了!< / p >

我为Firefox找到了一个非常简单的解决方案(只适用于相对而不是直接href):添加type="application/octet-stream":

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

我遇到了同样的问题,找到了一个迄今为止非常有效的解决方案。在.htaccess文件中放入以下代码:

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

它来自强制文件下载,而不是在浏览器中显示 . .

使用download属性,但要考虑到它只适用于与您的代码位于同一源中的文件。这意味着用户只能下载来自源站点、同一主机的文件。

用原始文件名下载:

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

“some_name”作为文件名下载:

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

添加target="_blank"时,我们将使用一个新的选项卡,而不是实际的选项卡,而且在某些情况下,它将有助于download属性的正确行为。

它遵循与同源策略相同的规则。你可以在MDN Web Doc同源策略页面了解更多关于这个策略的信息

你可以在MDN Web Doc锚的属性页面上了解更多关于这个下载HTML5属性的信息。

如果你需要强制下载页面上的单个链接,一个非常简单的方法就是使用href-link中的HTML5 download-属性。

看:http://davidwalsh.name/download-attribute

有了这个,你可以重命名用户将下载的文件,同时它强制下载。

这是否是一种好的做法一直存在争议,但在我的情况下,我有一个PDF文件的嵌入式查看器,查看器不提供下载链接,所以我必须单独提供一个。在这里,我希望确保用户不会在web浏览器中打开PDF文件,否则会令人困惑。

这将不需要打开另存为对话框,但将下载链接直接到预设的下载目的地。当然,如果你是为别人做一个网站,需要他们手动写属性到他们的链接可能是一个坏主意,但如果有办法让属性到链接,这可能是一个简单的解决方案。

尝试将这一行添加到.htaccess文件中。

AddType application/octet-stream .pdf

I hope it'll work as it is browser independent.

在HTML代码中的文件名之后,我添加了?forcedownload=1

对我来说,这是触发对话框进行保存或下载的最简单方法。

只要把下面的代码放在你的.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);

服务器端解决方案更具兼容性,直到“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()

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

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

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

在我的JSP文件中,有一个表显示zip文件中的所有文件,其中的链接是:onclick='download?zip=<%=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。

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

它适用于Firefox:

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

这是旧的帖子,但这是一个我的解决方案在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和任何其他系统或自定义网站来说都是很棒的。

添加响应头Content-Disposition:附件;后面跟着文件名。删除Meta Content-Disposition;Inline;哪个会在同一个窗口中打开文档

在java中,它被设置为

response.setHeader("Content-Disposition", "attachment;filename=test.jpg");
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")