我正在尝试从客户端 JavaScript(在浏览器中)调用 Github REST API。
我的代码执行以下操作(我正在尝试获取包含私有(private)存储库的分支 mkdocs_page
的 zip):
const endpoint = 'https://api.github.com';
const resource = '/repos/astariul/private-gh-pages/zipball/mkdocs_page';
const options = {
mode: 'cors',
headers: {
'Authorization': 'Basic ' + btoa(`${pat}`), // pat contains my Personal Access Token
}
}
return fetch(`${endpoint}${resource}`, options);
控制台错误消息:
Access to fetch at 'https://api.github.com/repos/astariul/private-gh-pages/zipball/mkdocs_page' from origin 'null' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
在调试过程中,我尝试使用curl
重现该问题。当我指定经过身份验证的请求时,它会起作用:
curl --user "<my_PAT_token>" -i https://api.github.com/repos/astariul/private-gh-pages/zipball/mkdocs_page -X OPTIONS
HTTP/1.1 204 No Content
但是如果请求未经身份验证,则不起作用:
curl -i https://api.github.com/repos/astariul/private-gh-pages/zipball/mkdocs_page -X OPTIONS
HTTP/1.1 404 Not Found
注意:当我尝试获取主分支(无论是否经过身份验证)时,它工作正常。然而,当被重定向时它会失败:
Access to fetch at 'https://codeload.github.com/astariul/private-gh-pages/legacy.zip/refs/heads/main?token=XXX' (redirected from 'https://api.github.com/repos/astariul/private-gh-pages/zipball') from origin 'null' 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. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
这是 Github API 中的错误吗?或者我做错了什么?
最佳答案
无法在预检请求中强制进行身份验证。预检完全由浏览器控制,并且不会以任何可以从前端 JavaScript 代码操作的方式公开任何内容。 CORS 协议(protocol)的要求明确禁止浏览器在预检请求中包含任何凭据。
详细解释参见 https://stackoverflow.com/a/45406085/ 的答案.
由于预检涉及浏览器发出 OPTIONS
请求,因此一般来说,如果服务器需要对特定资源的 OPTIONS
请求进行身份验证(这似乎是问题中引用的 GitHub URL 的情况)这根本不一定是意外错误。
这是因为执行预检并发送 OPTIONS
请求的唯一正常情况是前端 JavaScript 代码在浏览器中运行的情况。从服务器端代码或从 shell/命令行环境中运行的代码或从桌面应用或 native 移动应用发出的请求不涉及发送 OPTIONS
请求。
因此,如果提供者实际上打算从浏览器中运行的前端代码使用它,那么缺乏对对特定资源的未经身份验证的 OPTIONS 请求的支持只会是一个错误。换句话说,它可以表明提供者故意不希望从前端 JavaScript 代码中使用它(问题中引用的 URL 似乎就是这种情况)。
关于javascript - 如何在预检请求中强制进行身份验证?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68143581/