You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular应用调用GitHub REST API下载仓库压缩包遇CORS错误

Angular应用获取GitHub仓库Zip包的CORS问题解决

问题背景

我在部署于GitHub Pages(绑定自定义已验证域名)的Angular应用中,尝试获取公开仓库的Zip压缩包,用于后续JSZip处理。初始调用GitHub API的代码如下:

public getTemplate() {
  return this.http.get(
    'https://api.github.com/repos/crystal-nest/cobweb-mod-template/zipball/1.20.4',
    {
      headers: {
        'X-GitHub-Api-Version': '2022-11-28'
      }
    }
  );
}

该URL在浏览器直接访问可正常下载,但代码执行时触发CORS拦截:

Access to XMLHttpRequest at 'https://codeload.github.com/Crystal-Nest/cobweb-mod-template/legacy.zip/refs/heads/1.20.4' (redirected from 'https://api.github.com/repos/crystal-nest/cobweb-mod-template/zipball/1.20.4') from origin 'https://crystalnest.it' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

尝试改用JSONP请求:

return this.http.jsonp('https://api.github.com/repos/crystal-nest/cobweb-mod-template/zipball/1.20.4', 'callback');

仍失败,收到JSONP错误:

{
    "headers": {
        "normalizedNames": {},
        "lazyUpdate": null,
        "headers": {}
    },
    "status": 0,
    "statusText": "JSONP Error",
    "url": "https://api.github.com/repos/crystal-nest/cobweb-mod-template/zipball/1.20.4?callback=ng_jsonp_callback_0",
    "ok": false,
    "name": "HttpErrorResponse",
    "message": "Http failure response for https://api.github.com/repos/crystal-nest/cobweb-mod-template/zipball/1.20.4?callback=ng_jsonp_callback_0: 0 JSONP Error",
    "error": {
        "message": "JSONP injected script did not invoke callback.",
        "stack": "Error: JSONP injected script did not invoke callback.\n    stacktrace omitted for the sake of brevity"
    }
}

另外,我更偏好使用https://github.com/crystal-nest/cobweb-mod-template/archive/refs/heads/1.20.4.zip这个URL,它返回的压缩包命名规整,不会附加随机代码,更便于JSZip处理。

可行解决方案

1. 后端代理(生产环境首选)

由于GitHub的codeload域名不允许跨域请求,最可靠的方式是通过后端服务代理请求:

  • 搭建简单后端接口或使用无服务器函数(如Cloudflare Workers、Vercel Edge Functions),由后端请求GitHub的Zip URL,再将文件内容返回给前端。
  • 前端调用同域名的代理接口,避免CORS拦截。

示例Cloudflare Workers代理代码(简化版):

export default {
  async fetch(request) {
    const githubUrl = 'https://github.com/crystal-nest/cobweb-mod-template/archive/refs/heads/1.20.4.zip';
    const response = await fetch(githubUrl);
    return new Response(response.body, {
      headers: {
        'Access-Control-Allow-Origin': 'https://crystalnest.it', // 指定你的自定义域名
        'Content-Type': response.headers.get('Content-Type')
      }
    });
  }
};

2. 直接触发浏览器下载(无需前端处理内容时使用)

如果不需要在前端用JSZip处理文件,只是让用户下载,可直接创建a标签跳转,绕开AJAX的CORS限制:

public downloadTemplate() {
  const url = 'https://github.com/crystal-nest/cobweb-mod-template/archive/refs/heads/1.20.4.zip';
  const link = document.createElement('a');
  link.href = url;
  link.download = 'cobweb-mod-template-1.20.4.zip';
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
}

3. 临时使用公开CORS代理(仅测试用)

公开CORS代理服务可临时解决问题,但存在流量限制和安全风险,不建议生产环境使用:
将请求URL包装为代理地址,例如:

const proxyUrl = 'https://cors-anywhere.herokuapp.com/';
const targetUrl = 'https://github.com/crystal-nest/cobweb-mod-template/archive/refs/heads/1.20.4.zip';
return this.http.get(proxyUrl + targetUrl, { responseType: 'arraybuffer' });

内容的提问来源于stack exchange,提问作者CrystalSpider

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 06:45:14