使用jQuery JSONP跨域下载Zip文件失败,请求状态200却报错
嘿,我来帮你解决这个跨域下载Zip文件的问题~
首先得明确:JSONP完全不适合用来下载二进制文件,这也是你报错的根本原因。JSONP的原理是通过动态插入<script>标签加载内容,浏览器会把加载到的内容当成JavaScript代码解析——但你请求的是Zip二进制文件,完全不是合法的JS语法,所以必然会抛出Uncaught SyntaxError: Invalid or unexpected token,哪怕请求状态是200也没用。
下面给你两个可行的解决方案,根据你的需求选就行:
方案1:最简单直接的方法——创建隐藏<a>标签触发下载
这种方法不需要AJAX,直接利用浏览器原生的下载行为,而且不受AJAX的同源限制(因为是浏览器发起的普通GET请求,不是AJAX请求),大部分静态文件服务器都支持:
// 绑定到按钮点击事件的函数 function triggerZipDownload() { const zipUrl = "http://www.touchwand.com/wp-content/uploads/2018/04/Icons-and-backgrounds.zip"; // 创建隐藏的a标签 const downloadLink = document.createElement('a'); downloadLink.href = zipUrl; // 可选:指定下载后的文件名,如果不设置会用URL里的默认文件名 downloadLink.download = 'Icons-and-backgrounds.zip'; // 隐藏标签 downloadLink.style.display = 'none'; // 添加到页面并触发点击 document.body.appendChild(downloadLink); downloadLink.click(); // 点击后移除标签 document.body.removeChild(downloadLink); }
把这个函数绑定到你的按钮onclick事件上,点击后浏览器就会直接触发下载,完美避开跨域问题。
方案2:需要监听下载状态?用Fetch + Blob(需服务器支持CORS)
如果你的需求是要监听下载进度、处理错误状态,那可以用Fetch API配合Blob,但前提是目标服务器配置了CORS(返回Access-Control-Allow-Origin响应头,允许你的域名访问):
async function downloadZipWithStatus() { try { const response = await fetch("http://www.touchwand.com/wp-content/uploads/2018/04/Icons-and-backgrounds.zip"); // 检查请求是否成功 if (!response.ok) { throw new Error(`请求失败,状态码:${response.status}`); } // 将响应转为Blob对象 const zipBlob = await response.blob(); // 创建临时URL const tempUrl = URL.createObjectURL(zipBlob); // 同样用a标签触发下载 const downloadLink = document.createElement('a'); downloadLink.href = tempUrl; downloadLink.download = 'Icons-and-backgrounds.zip'; downloadLink.click(); // 释放临时URL占用的内存 URL.revokeObjectURL(tempUrl); } catch (error) { console.error('下载出错啦:', error); // 这里可以添加错误提示逻辑,比如给用户弹个框 } }
如果服务器没配置CORS,这个方法会报跨域错误,这时候还是方案1更靠谱。
总结一下:JSONP是用来跨域获取JSON数据的,完全不适用于二进制文件下载,换成上面的方法就能解决问题啦~
内容的提问来源于stack exchange,提问作者Hairi
相关产品推荐
相关产品推荐

