文件下载

33 篇文章 0 订阅
文件下载,在我们的项目中,基本都会用到,记得写过好多次了,但每次写,只有个大概印象,又需要重新找。今天项目中,涉及到了 "多图下载",点击按钮,同时下载多张图片。好好总结下下载,避免以后每次要写了,需要来回找资料!

1.前端下载
	我们可以直接通过 <a> 来下载文件
		<a href="downloads/test.jpg">下载 .jpg 图片</a>
		<a href="downloads/test.pdf">下载 .pdf 文件</a>
		<a href="downloads/test.zip">下载 .zip 文件</a>
		<a href="downloads/test.exe">下载 .exe 文件</a>

	上面 4 种不同类型的文件,.jpg 和 .pdf,会直接通过浏览器打开文件,而 .zip 和 .exe 会直接下载下来。

	为什么会出现这种区别?
		没怎么了解,应该是浏览器直接能解析,这类型的文件,所以就不会下载!

	如何下载浏览器也可以解析的,类似 .jpg 和 .pdf 的文件?
		<a> 标签还支持一个 download 属性
			1>不传值
				<a href="downloads/test.jpg" download>下载 .jpg 图片</a>
			2>传值,允许修改文件名
				<a href="downloads/test.jpg" download="test1.jpg">下载 .jpg 图片</a>

	切记!!!
		通过 <a> 链接的方式,来下载文件,必须是 "同源 URL",不可跨域!!!

	此外:
		还可以使用 href 还可以是:blob:URLs 和 data:URLs,让我们可以下载 javascript 生成的内容(例如:使用 canvas 生成的dataUrl)

		/*
			var link = document.createElement('a');
			link.innerHTML = 'download image';

			link.addEventListener('click', function(ev) {
			    link.href = canvas.toDataURL();
			    link.download = "mypainting.png";
			}, false);

			document.body.appendChild(link);
		*/

	参考文章:
		https://www.tutorialrepublic.com/php-tutorial/php-file-download.php
		https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/a

2.后端PHP下载
	前端,用户在页面上点击一个 <a>,href 指向到我们的 PHP 处理文件,PHP 文件里通过设置 header 头,然后输出文件内容,从而达到下载的目的

	<a href="/download.php?file=test.jpg">下载 .jpg 图片</a>

	download.php
		<?php
			$file = $_GET['file'];
		    $file = urldecode($_REQUEST["file"]); // Decode URL-encoded string
		    $filepath = "images/" . $file;

			if(file_exists($file)){
		        header('Content-Description: File Transfer');
		        header('Content-Type: application/octet-stream');
		        header('Content-Disposition: attachment; filename="'.basename($filepath).'"');
		        header('Expires: 0');
		        header('Cache-Control: must-revalidate');
		        header('Pragma: public');
		        header('Content-Length: ' . filesize($filepath));
		        flush(); // Flush system output buffer
		        readfile($filepath);
			}

	参考文章:
		https://www.tutorialrepublic.com/php-tutorial/php-file-download.php

	PHP 这种下载方式,基本是个通用方法,网上这方面资料太多了,大同小异,只是 header() 头配置略微不同。我们在 PHP 官方文档中,也可以参考:
		http://php.net/manual/zh/function.header.php 		// 搜索 download 关键字
		http://php.net/manual/en/function.readfile.php 		// 搜索 download 关键字 

3.点击下载按钮,同时下载多个文件
	起先是网上,搜了好多篇,都是说的是将多个文件,打包为 .zip 文件,然后下载!
	这尼玛明显不是我想要的啊,可能是我自己的搜索关键字描述有问题!

	我是没仔细看,看到了:
		1>zip 打包技术
		2>还有组装 <iframe></iframe> 嵌套 <form>
		3>也有比较合理的方法,和我自己想的一样,接下来描述

	比较合理的方法:
		既然我们可以使用 <a href="" download> 来下载单个文件,能不能我们通过点击一个按钮,然后让它来触发多个我们要下载的 <a href="" download> 链接?

		代码:
			<a id="one" href="downloads/test.jpg" style="display: none;">下载 .jpg 图片</a>
			<a id="two" href="downloads/test.pdf" style="display: none;">下载 .pdf 文件</a>
		    <button id="download">下载</button>

		    <script>
		    	$('#download').click(function(){
		    		$('#one').click();
		    		$('#two').click();
		    	});
		    </script>

		结果,可以完美下载!!

		对于 "跨域文件",和之前讲到的方法一样,只要 href 改为 PHP 请求即可:
			<a id="one" href="/test/test?file=test.jpg" style="display: none;">下载 .jpg 图片</a>
			<a id="two" href="/test/test?file=test.pdf" style="display: none;">下载 .pdf 文件</a>

	代码优化:
		原理就是这个,过程的话,我们稍微优化下写法:
	    <button onClick="download(window.downloadFiles)">下载</button>
		<script>
			var downloadFiles = [
				{'link': 'downloads/test.jpg', 'name': 'test1.jpg'},
				{'link': 'downloads/test.pdf', 'name': 'test1.pdf'},
				{'link': 'downloads/test.zip', 'name': 'test1.zip'},
				{'link': 'downloads/test.exe', 'name': 'test1.exe'},
			];
			function download(files){
				var link = document.createElement('a');
				link.style.display = 'none';

				document.body.appendChild(link);

				for(var i = 0; i < files.length; i++){
					link.setAttribute('href', files[i].link)	
					link.setAttribute('download', (files[i].name ? files[i].name : null));
					link.click();
				}
				document.body.removeChild(link);
			}
		</script>

	参考文章:
		https://www.cnblogs.com/hustskyking/p/multiple-download-with-javascript.html(貌似很不错!我是写完了,才发现的)
		https://segmentfault.com/q/1010000012322615
		https://stackoverflow.com/questions/16390601/make-multiple-files-to-force-download
		https://stackoverflow.com/questions/1754352/download-multiple-files-as-a-zip-file-using-php
		https://stackoverflow.com/questions/18451856/how-can-i-let-a-user-download-multiple-files-when-a-button-is-clicked
		https://stackoverflow.com/questions/2339440/download-multiple-files-with-a-single-action/9425731#9425731

4.文件下载时,我们可能需要判断文件是否存在
	is_file()
	file_exists()

	这 2 个函数,都不能检测到 "远程文件" 是否存在

	同样的实现方式很多,这里先写上几种:
		1>fopen
			$url = '';
			$handle = @fopen($url, 'r');
			if($handle){
				// 存在
			}else{
				// 不存在
			}

		2>curl
	        $ch = curl_init();
	        curl_setopt($ch, CURLOPT_URL, $url);
	        curl_setopt($ch, CURLOPT_NOBODY, true);		// 注意:不请求内容,优化
	        curl_setopt($ch, CURLOPT_FAILONERROR, true);
	        curl_setopt($ch, CURLOPT_TIMEOUT, 10);
	        $res = curl_exec($ch);
	        if ($res !== false){ 
	        	// 存在
	        }else{
	        	// 不存在
	        }
	        curl_close($ch);

	    3>get_headers
	    	$header_response = @get_headers($url, 1);
	    	if ( strpos( $header_response[0], "404" ) !== false ){
	    		// 不存在
	    	}else{
	    		// 存在
	    	}

	3个都测试了下,速度差不了多少...

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值