J'ai des catalogues PDF de grande taille sur mon site Web et je dois les relier par téléchargement. Quand j'ai googlé, j'ai trouvé une chose telle que notée ci-dessous. Il devrait ouvrir la fenêtre contextuelle "Enregistrer sous ..." en cliquant sur le lien ...
<head>
<meta name="content-disposition" content="inline; filename=filename.pdf">
...
Mais cela ne fonctionne pas:/Lorsque je fais un lien vers un fichier comme ci-dessous, il crée simplement un lien vers un fichier et tente d'ouvrir le fichier.
<a href="filename.pdf" title="Filie Name">File name</a>
UPDATE (selon les réponses ci-dessous):
À mon avis, il n’existe pas de solution multi-navigateurs fiable à 100%. La meilleure façon consiste probablement à utiliser l'un des services Web énumérés ci-dessous et à donner un lien de téléchargement ...
D'une réponse à - Forcer un navigateur à enregistrer le fichier après avoir cliqué sur le lien:
<a href="path/to/file" download>Click here to download</a>
<a href="file link" download target="_blank">Click here to download</a>
Cela fonctionne pour moi dans Firefox et Chrome.
Les balises META ne sont pas un moyen fiable d'atteindre ce résultat. En règle générale, vous ne devriez même pas le faire - cela devrait être laissé à l'utilisateur/à l'agent utilisateur de décider de l'utilisation du contenu que vous fournissez. L'utilisateur peut toujours forcer son navigateur à télécharger le fichier s'il le souhaite.
Si vous souhaitez toujours forcer le navigateur à télécharger le fichier, modifiez directement les en-têtes HTTP. Voici un exemple de code 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
Notez qu'il ne s'agit que d'une extension du protocole HTTP. certains navigateurs peuvent l’ignorer de toute façon.
J'ai eu le même problème et j'ai trouvé une solution qui a très bien fonctionné jusqu'à présent. Vous mettez le code suivant dans votre fichier .htaccess
:
<FilesMatch "\.(?i:pdf)$">
ForceType application/octet-stream
Header set Content-Disposition attachment
</FilesMatch>
Il venait de Forcer le téléchargement d'un fichier au lieu de s'afficher dans le navigateur.
J'ai trouvé une solution très simple pour Firefox (ne fonctionne qu'avec un parent plutôt qu'un href direct): ajoutez type="application/octet-stream"
:
<a href="./file.pdf" id='example' type="application/octet-stream">Example</a>
Essayez d’ajouter cette ligne à votre fichier .htaccess.
AddType application/octet-stream .pdf
J'espère que cela fonctionnera car il est indépendant du navigateur.
Cela se produit généralement, car certains paramètres de navigateur ou plug-ins ouvrent directement PDF dans la même fenêtre, comme une simple page Web.
Ce qui suit pourrait vous aider. Je l'ai fait dans PHP il y a quelques années. Mais actuellement, je ne travaille pas sur cette plateforme.
<?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>";
}
?>
Enregistrez ce qui précède sous download.php.
Enregistrez ce petit extrait sous forme de fichier PHP quelque part sur votre serveur. Vous pouvez l'utiliser pour télécharger un fichier dans le navigateur plutôt que de l'afficher directement. Si vous souhaitez servir des fichiers autres que PDF, supprimez ou modifiez la ligne 5.
Vous pouvez l'utiliser comme ceci:
Ajoutez le lien suivant à votre fichier HTML.
<a href="download.php?file=my_pdf_file.pdf">Download the cool PDF.</a>
Référence de: Ce blog
Il suffit de mettre le code ci-dessous dans votre fichier .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
Ou vous pouvez aussi faire un tour en JavaScript
element.setAttribute( 'download', whatever_string_you_want);
Je viens de l'utiliser, mais je ne sais pas si cela fonctionne sur tous les navigateurs.
Cela fonctionne dans Firefox:
<a href="myfile.pdf" download>Click to Download</a>
Un moyen très simple de le faire, si vous devez forcer le téléchargement pour un lien unique sur votre page, consiste à utiliser l'attribut de téléchargement HTML5 dans le lien href.
Voir: http://davidwalsh.name/download-attribute
avec cela, vous pouvez renommer le fichier que l'utilisateur va télécharger tout en forçant le téléchargement.
Il y a eu un débat sur le point de savoir si c'est une bonne pratique ou non, mais dans mon cas, j'ai un visualiseur intégré pour un fichier pdf et celui-ci n'offre pas de lien de téléchargement, je dois donc le fournir séparément. Ici, je veux m'assurer que l'utilisateur ne voit pas le fichier pdf ouvert dans le navigateur Web, ce qui serait déroutant.
Cela n'ouvrira pas nécessairement la fenêtre Enregistrer sous, mais le lien sera téléchargé directement vers la destination de téléchargement prédéfinie. Et bien sûr, si vous faites un site pour quelqu'un d'autre et que vous avez besoin d'écrire manuellement les attributs de leurs liens est probablement une mauvaise idée, mais s'il existe un moyen d'intégrer l'attribut dans les liens, cela peut être une solution légère.
Un moyen simple vraiment d'y parvenir, sans utiliser de sites de téléchargement externes ni de modifier les en-têtes, etc., consiste simplement à créer un fichier Zip avec le PDF à l'intérieur et à le lier directement au fichier Zip. Cela déclenchera TOUJOURS la boîte de dialogue Enregistrer/Ouvrir. Il est toutefois toujours facile pour les utilisateurs de double-cliquer sur la fenêtre PDF du programme associé à .Zip.
BTW bonne question, je cherchais aussi une réponse, car la plupart des plugins PDF intégrés au navigateur prennent tellement de temps pour afficher quoi que ce soit (et suspendra souvent le navigateur pendant le chargement du PDF).
Une solution côté serveur est plus compatible, jusqu'à ce que l'attribut "télécharger" soit implémenté dans tous les navigateurs.
Un exemple de Python pourrait être un gestionnaire de requêtes HTTP personnalisé pour un magasin de fichiers. Les liens qui pointent vers le magasin de fichiers sont générés comme suit:
http://www.myfilestore.com/filestore/13/130787e71/download_as/desiredName.pdf
Voici le code:
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()
Après le nom du fichier dans le code HTML, j'ajoute ?forcedownload=1
Cela a été le moyen le plus simple pour moi de déclencher une boîte de dialogue pour enregistrer ou télécharger.
Ceci est un vieux post mais voici celui de ma solution en JavaScript que d'utiliser la bibliothèque 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>
Vous devez simplement utiliser la classe force-download
dans votre balise <a>
et forcer le téléchargement automatiquement. Vous pouvez également l'ajouter au parent div
et récupérer tous les liens qu'il contient.
Exemple:
<a href="/some/good/url/Post-Injection_Post-Surgery_Instructions.pdf" class="force-download" target="_blank">Download PDF</a>
C'est parfait pour WordPress et tous les autres systèmes ou sites Web personnalisés.
Je viens d'avoir un problème très similaire avec le problème ajouté que j'avais besoin de créer des liens de téléchargement vers des fichiers au sein d'un fichier Zip.
J'ai d'abord essayé de créer un fichier temporaire, puis de fournir un lien vers le fichier temporaire, mais j'ai constaté que certains navigateurs afficheraient simplement le contenu (un fichier CSV Excel) plutôt que de proposer le téléchargement. Finalement, j'ai trouvé la solution en utilisant un servlet. Cela fonctionne à la fois sur Tomcat et GlassFish et je l'ai essayé sur Internet Explorer 10 et Chrome.
Le servlet prend en entrée un nom de chemin complet vers le fichier Zip, ainsi que le nom du fichier dans le fichier Zip à télécharger.
À l'intérieur de mon fichier JSP, j'ai un tableau affichant tous les fichiers du fichier Zip, avec des liens indiquant: onclick='download?zip=<%=Zip%>&csv=<%=csv%>'
Le code de servlet est dans 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;
}
}
}
}
Pour compiler sur Tomcat, le chemin d'accès aux classes doit inclure Tomcat\lib\servlet-api.jar ou GlassFish: glassfish\lib\j2ee.jar.
Mais l'un ou l'autre travaillera sur les deux. Vous devez également définir votre servlet dans web.xml
.
Si vous avez un plugin dans le navigateur qui sait comment ouvrir un fichier PDF, il s’ouvrira directement. Comme dans le cas des images et du contenu HTML.
L’approche alternative n’est donc pas d’envoyer votre type MIME dans la réponse. De cette façon, le navigateur ne saura jamais quel plugin devrait l'ouvrir. Par conséquent, il vous donnera une boîte de dialogue Enregistrer/Ouvrir .