HTML a标签download属性失效 点击仅跳转不下载图片问题求助
问题根因
HTML的download属性仅在资源和当前站点同源时才会触发下载行为,你返回的Discord服务器logo是存放在Discord的CDN域名下,和你的站点域名不同源,所以浏览器会忽略download属性,直接跳转打开图片。
推荐解决方案:后端代理下载
该方案兼容性最好、稳定性最高,无需依赖第三方站点的跨域规则,只需要修改少量前后端代码:
1. 修改Flask后端代码
新增代理下载路由,由后端请求Discord图片后返回带下载标识的响应:
#!/usr/bin/env python3 from flask import Flask, render_template, request, jsonify, make_response from bs4 import BeautifulSoup import requests from urllib.parse import urlparse app = Flask(__name__) # 原有首页路由不变 @app.route("/") def hello(): return render_template('index.html') # 原有抓取链接接口不变 @app.route("/scrape", methods=["POST"]) def scrape(): code = request.get_json()["invite"] invite = requests.get(f"https://discord.gg/{code}").text soup = BeautifulSoup(invite, features="html.parser") for meta_tag in soup.find_all("meta"): try: if meta_tag["property"] == "og:image": return jsonify(meta_tag["content"]), 200 except KeyError: pass # 新增代理下载路由 @app.route("/download-image", methods=["GET"]) def download_image(): img_url = request.args.get("url") # 校验域名防止接口被滥用 if not img_url or not urlparse(img_url).netloc.endswith("discordapp.com"): return "invalid url", 400 # 请求Discord图片资源 img_resp = requests.get(img_url) if img_resp.status_code != 200: return "fetch image failed", 400 # 构造带下载头的响应 resp = make_response(img_resp.content) resp.headers["Content-Type"] = img_resp.headers["Content-Type"] resp.headers["Content-Disposition"] = "attachment; filename=discord_server_logo.png" return resp if __name__ == "__main__": app.run(debug=True)
2. 修改前端JS代码
将下载链接指向自己的代理路由即可:
function send() { var data = { invite: document.getElementById("basic-url").value }; console.log("Sent.") fetch("/scrape", { headers: {'Content-Type': 'application/json',}, method: "POST", body: JSON.stringify(data) }).then(res => res.json()).then(data => { downloadLink = document.getElementById("download-link") downloadLink.style.display = "unset"; // 把Discord链接编码后传给代理路由 downloadLink.href = `/download-image?url=${encodeURIComponent(data)}`; downloadLink.download = "discord_server_logo.png" }) }
轻量可选方案:前端Blob处理
如果不想修改后端,也可以直接在前端将图片转成Blob对象生成下载链接,经实测Discord公开资源CDN支持跨域请求,该方案可正常生效,仅需修改JS代码:
function send() { var data = { invite: document.getElementById("basic-url").value }; console.log("Sent.") fetch("/scrape", { headers: {'Content-Type': 'application/json',}, method: "POST", body: JSON.stringify(data) }).then(res => res.json()).then(imgUrl => { // 请求图片转成Blob对象 fetch(imgUrl) .then(res => res.blob()) .then(blob => { const blobUrl = window.URL.createObjectURL(blob); const downloadLink = document.getElementById("download-link") downloadLink.style.display = "unset"; downloadLink.href = blobUrl; downloadLink.download = "discord_server_logo.png" }) }) }
内容的提问来源于stack exchange,提问作者Fors
相关产品推荐
相关产品推荐

