vue实现非同源图片的下载功能--跨域问题(解决浏览器打开图片,而不是下载)

本文详细介绍了如何在接收到后端返回的图片URL后,通过HTML5的a标签download属性实现图片下载功能。针对跨域图片下载的问题,利用canvas和Blob对象进行处理,确保图片能够成功下载。提供的代码示例可用于直接应用,同时也适用于Vue.js环境。此外,文章还分享了学习图片下载的相关资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、需求

我刚接到需求的时候,思维比较混乱。
需求:在xxx页面添加批量下载xxxx图片功能。给了后端返回的图片url。

二、思路

初始思路是使用a标签的download属性
下载图片的具体实现效果demo,点击链接:https://www.w3school.com.cn/tiy/t.asp?f=html_a_download
效果图:


在这里插入图片描述


注意!!!

download 是 a 标签 html5 的新属性,可以点击下载文件。初次使用,经常出现无法点击的情况,可能有以下原因,排除下:

解决方案:

  • 必须设置 href 属性,download 才起作用;
  • download 属性是文件名,href 属性,指向的是要下载的文件;
  • href 的指向需要同源,跨域下载不下来,当然可以通过其他方案,比如把图片传到自己后台,再返回同源的路径;

三、完成

a标签的download属性 只适用于同源的图片,如果是 非同源图片,a标签的download属性下载的图片会在浏览器中打开。 html代码生成 canvas 然后生成图片。但是html里面的图片路径必须用base64。解法如下:
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
</body>
<script>
    var imgSrc = 'https://profile.csdnimg.cn/2/C/7/3_wangbadandzy'
    var name = "测试图片"

    function downloadPicture(imgSrc, name) {
        const image = new Image()
            // 解决跨域 Canvas 污染问题
        image.setAttribute('crossOrigin', 'anonymous')
        image.onload = () => {
            const canvas = document.createElement('canvas')
            canvas.width = image.width
            canvas.height = image.height
            const context = canvas.getContext('2d')
            context.drawImage(image, 0, 0, image.width, image.height)
            const url = canvas.toDataURL('image/jpg')
            const a = document.createElement('a')
            a.download = name || 'phone'
            a.href = url
            a.click()
            a.remove()
        }
        image.src = imgSrc
    }
    downloadPicture(imgSrc)
</script>

</html>

其中,下载的图片可能遇到了“网络错误”,没有完成下载。使用 Blob 解决。

最终代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
</body>
<script>
    var imgSrc = 'https://profile.csdnimg.cn/2/C/7/3_wangbadandzy'
    var name = "测试图片"

    function downloadPicture(imgSrc, name) {
        const image = new Image()
            // 解决跨域 Canvas 污染问题
        image.setAttribute('crossOrigin', 'anonymous')
        image.onload = () => {
            const canvas = document.createElement('canvas')
            canvas.width = image.width
            canvas.height = image.height
            const context = canvas.getContext('2d')
            context.drawImage(image, 0, 0, image.width, image.height)
            canvas.toBlob((blob) => {
                const url = URL.createObjectURL(blob)
                const a = document.createElement('a')
                a.download = name || 'photo'
                a.href = url
                a.click()
                a.remove()
                URL.revokeObjectURL(url)
            })
        }
        image.src = imgSrc
    }
    downloadPicture(imgSrc, name)
</script>

</html>

结语,这个函数可以直接拿去用,vue的解决方式和js相同。

四、链接

学习图片下载的链接:
Vue下载图片时出现"Access-Control-Allow-Origin"头问题,这是由于浏览器的同源策略所导致的。同源策略要求网页只能请求同源(协议、名、端口号都相同)的资源,而不能直接请求其他名下的资源。 解决这个问题的方法有两种: 1. 在后端服务器上设置响应头,允许访问。在服务器端的响应中添加"Access-Control-Allow-Origin"头,将其值设置为"*"或指定允许访问的名。例如,在Java Spring Boot中可以使用@CrossOrigin注解来实现访问控制。 2. 使用代理服务器。在Vue项目的配置文件(vue.config.js)中配置代理服务器,将请求转发到后端服务器。这样,前端代码就可以通过代理服务器来请求后端资源,避免了问题。 下面是两种解决方法的示例: 1. 在后端服务器上设置响应头 ```java @CrossOrigin(origins = "http://localhost:8080") @RestController public class MyController { @GetMapping("/downloadImage") public void downloadImage(HttpServletResponse response) { // 设置响应头,允许访问 response.setHeader("Access-Control-Allow-Origin", "*"); // 下载图片的逻辑 // ... } } ``` 2. 使用代理服务器 在vue.config.js中添加以下配置: ```javascript module.exports = { devServer: { proxy: { '/api': { target: 'http://localhost:8085', changeOrigin: true, pathRewrite: { '^/api': '' } } } } } ``` 然后在Vue组件中发送请求时,将请求路径改为代理服务器的路径: ```javascript axios.get('/api/downloadImage') .then(response => { // 处理响应数据 }) .catch(error => { // 处理错误 }); ```
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值