我正在尝试使用自定义验证域构建托管在我的 GitHub 页面上的 Angular 应用程序。
这是我调用 GitHub API 并获取我的(公共)存储库的 zip 存档的代码:
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 是正确的,因为如果我将其粘贴到浏览器中,下载就会开始。
但是,当代码执行时,我收到以下错误:
访问“https://codeload.github.com/Crystal-Nest/cobweb-mod-template/legacy.zip/refs/heads/1.20.4”处的 XMLHttpRequest(重定向自“https://api.github.com”) com/repos/crystal-nest/cobweb-mod-template/zipball/1.20.4') 来自来源 'https://crystalnest.it' 已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。
然后我尝试使用 JSONP 请求:
return this.http.jsonp('https://api.github.com/repos/crystal-nest/cobweb-mod-template/zipball/1.20.4', 'callback');
但是这次我收到的错误是:
{
"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"
}
}
我的代码可以在这里找到,这里有一个实例(点击下载按钮并忽略其他一切,该网站目前正在开发中)。
旁注:即使请求有效并且我能够以
'arraybuffer'
的形式获取文件(使用 JSZip 处理文件所需的数据),zip 名称及其根目录附加了代码,这很痛苦最后(我无法理解它是什么,因此我无法预测它会是什么)。理想情况下,我想使用这个 URL https://github.com/crystal-nest/cobweb-mod-template/archive/refs/heads/1.20.4.zip
,因为它给了我一个易于预测的名称,因此易于处理。
正如 GitHub 社区论坛所指出的,当前唯一的方法是使用代理。
特别是,我必须做的是:
在
proxy.conf.json
下添加src
,内容如下:
{
"/repo/**": {
"target": "https://codeload.github.com/",
"secure": true,
"pathRewrite": {
"^/repo": ""
},
"changeOrigin": true
}
}
(此文件的内容描述于here)
在我的
angular.json
中引用此文件:
{
"architect": {
"serve": {
"options": {
"proxyConfig": "src/proxy.conf.json"
}
}
}
}
然后我的服务方法就变成了:
public getTemplate(minecraftVersion: MinecraftVersion) {
return this.http.get(`/repo/crystal-nest/cobweb-mod-template/zip/refs/heads/1.20.4`, {responseType: 'arraybuffer'});
}
这样做的一个好处是我可以使用前面提到的 URL (
https://github.com/crystal-nest/cobweb-mod-template/archive/refs/heads/1.20.4.zip
)。https://codeload.github.com/crystal-nest/cobweb-mod-template/zip/refs/heads/1.20.4
,我必须使用后者而不是前者,否则我会再次收到 CORS 错误。