前端下载外部网络图片

背景

最近做项目跟第三方对接的时候遇到一个需求:第三方的图片信息保存在我们的数据库里,要求在我们的系统可以直接下载图片。

方法一,a标签加downlaod属性

本来以为直接在前端用个a标签加个download属性就可以了,像下面这样

1
<a href="xxxx.com/file/123.jpg" download>下载</a>

结果试了之后发现居然不可以下载,它会直接跳转到一个新的页面然后打开图片。

网上搜索之后发现是因为这个图片不是保存在本机服务器上的

方法二,转base64

然后试了下把图片转base64之后再下载,结果发现转base64的时候,报了一个跨域的错误信息。

方法三,用downloadjs插件

1
地址 https://www.npmjs.com/package/downloadjs

看网上有人在说用这个插件可以下载,试了下,还是不行。

方法四,后端处理,文件流

最后用后端处理的方式解决了。

比如后端把”sev7n.cn/downloadFile”这个地址给前端

前端直接访问这个地址,就可以直接下载

php代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/**
* @param string $file_url 文件地址
* @param string $file_name 文件名
*/
public function downloadFile($file_url,$file_name="")
{
if (!$file_url) {
return false;
}

//设置浏览器下载的文件名
$file_name = $file_name ?: basename($file_url);

//获取远程文件大小
//注意filesize()无法获取远程文件大小
$headers = get_headers($file, 1);
$fileSize = $headers['Content-Length'];

// 设置header头
// 因为不知道文件是什么类型的,告诉浏览器输出的是字节流
header('Content-Type: application/octet-stream');
// 告诉浏览器返回的文件大小类型是字节
header('Accept-Ranges:bytes');
// 告诉浏览器返回的文件大小
header('Content-Length: ' . $fileSize);
// 告诉浏览器文件作为附件处理并且设定最终下载完成的文件名称
header('Content-Disposition: attachment; filename="' . $file_name . '"');

//针对大文件,规定每次读取文件的字节数为4096字节,直接输出数据
$read_buffer = 4096;
$handle = fopen($file_url, 'rb');
//总的缓冲的字节数
$sum_buffer = 0;
//只要没到文件尾,就一直读取
while (!feof($handle)) {
$sum_buffer += $read_buffer;
echo fread($handle, $read_buffer);

}
fclose($handle);

return true;
}

-------------完!感谢阅读-------------