gpt4 book ai didi

javascript - 请求的资源上不存在 'Access-Control-Allow-Origin' header —尝试从 REST API 获取数据时

转载 作者:行者123 更新时间:2023-12-01 16:52:51 26 4
gpt4 key购买 nike

我正在尝试从 HP Alm 的 REST API 获取一些数据。它与一个小的 curl 脚本配合得很好 - 我得到了我的数据。

现在使用 JavaScript、fetch 和 ES6(或多或少)这样做似乎是一个更大的问题。我不断收到此错误消息:

Fetch API cannot load . Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:3000' is therefore not allowed access. The response had HTTP status code 501. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.



我知道这是因为我试图从我的本地主机中获取该数据,并且解决方案应该使用 CORS。现在我以为我真的这样做了,但不知何故它要么忽略了我在标题中写的内容,要么问题出在别的地方?

那么,是否存在实现问题?我做错了吗?不幸的是,我无法检查服务器日志。我真的有点卡在这里了。
function performSignIn() {

let headers = new Headers();

headers.append('Content-Type', 'application/json');
headers.append('Accept', 'application/json');

headers.append('Access-Control-Allow-Origin', 'http://localhost:3000');
headers.append('Access-Control-Allow-Credentials', 'true');

headers.append('GET', 'POST', 'OPTIONS');

headers.append('Authorization', 'Basic ' + base64.encode(username + ":" + password));

fetch(sign_in, {
//mode: 'no-cors',
credentials: 'include',
method: 'POST',
headers: headers
})
.then(response => response.json())
.then(json => console.log(json))
.catch(error => console.log('Authorization failed : ' + error.message));
}

我正在使用 Chrome。我也尝试使用该 Chrome CORS 插件,但随后我收到另一条错误消息:

The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://127.0.0.1:3000' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

最佳答案

这个答案涵盖了很多方面,所以它分为三个部分:

  • 如何使用 CORS 代理解决“No Access-Control-Allow-Origin header”问题
  • 如何避免 CORS 预检
  • 如何解决“Access-Control-Allow-Origin header 不能是通配符”问题

  • 如何使用 CORS 代理避免“No Access-Control-Allow-Origin header”问题
    如果您不控制前端代码向其发送请求的服务器,那么来自该服务器的响应的问题只是缺少必要的 Access-Control-Allow-Origin header ,您仍然可以通过 CORS 代理发出请求来使事情工作。
    您可以使用来自 https://github.com/Rob--W/cors-anywhere/ 的代码轻松运行您自己的代理。 .
    您还可以在短短 2-3 分钟内轻松将自己的代理部署到 Heroku,使用 5 个命令:
    git clone https://github.com/Rob--W/cors-anywhere.git
    cd cors-anywhere/
    npm install
    heroku create
    git push heroku master
    运行这些命令后,您最终将拥有自己的 CORS Anywhere 服务器,例如,运行在 https://cryptic-headland-94862.herokuapp.com/ .
    现在,使用代理的 URL 作为请求 URL 的前缀:
    https://cryptic-headland-94862.herokuapp.com/https://example.com
    添加代理 URL 作为前缀会导致请求通过您的代理发出,然后:
  • 将请求转发到 https://example.com .
  • 接收来自 https://example.com 的响应.
  • 添加 Access-Control-Allow-Origin响应头。
  • 将带有添加的 header 的响应传递回请求前端代码。

  • 然后浏览器允许前端代码访问响应,因为该响应带有 Access-Control-Allow-Origin响应头是浏览器看到的。
    即使请求是触发浏览器执行 CORS 预检 OPTIONS 的请求也是如此。请求,因为在这种情况下,代理也会发回 Access-Control-Allow-HeadersAccess-Control-Allow-Methods使预检成功所需的 header 。

    如何避免 CORS 预检
    问题中的代码会触发 CORS 预检——因为它发送了 Authorization标题。
    https://developer.mozilla.org/docs/Web/HTTP/Access_control_CORS#Preflighted_requests
    即使没有那个, Content-Type: application/json header 也会触发预检。
    “预检”是什么意思:在浏览器尝试之前 POST在问题的代码中,它会首先发送一个 OPTIONS向服务器发出请求 — 确定服务器是否选择接收跨域 POSTAuthorizationContent-Type: application/json标题。

    It works pretty well with a small curl script - I get my data.


    使用 curl 正确测试,您必须模拟预检 OPTIONS浏览器发送的请求:
    curl -i -X OPTIONS -H "Origin: http://127.0.0.1:3000" \
    -H 'Access-Control-Request-Method: POST' \
    -H 'Access-Control-Request-Headers: Content-Type, Authorization' \
    "https://the.sign_in.url"
    ...与 https://the.sign_in.url替换为您实际使用的任何内容 sign_in网址是。
    浏览器需要从中看到的响应 OPTIONS请求必须有这样的 header :
    Access-Control-Allow-Origin:  http://127.0.0.1:3000
    Access-Control-Allow-Methods: POST
    Access-Control-Allow-Headers: Content-Type, Authorization
    如果 OPTIONS响应不包含这些 header ,那么浏览器就会停在那里,甚至不会尝试发送 POST要求。此外,响应的 HTTP 状态代码必须是 2xx——通常是 200 或 204。如果是任何其他状态代码,浏览器将在那里停止。
    问题中的服务器正在响应 OPTIONS带有 501 状态代码的请求,这显然意味着它试图表明它没有实现对 OPTIONS 的支持要求。在这种情况下,其他服务器通常以 405“不允许方法”状态代码响应。
    所以你永远做不到 POST如果服务器响应该 OPTIONS,则直接从您的前端 JavaScript 代码请求该服务器。使用 405 或 501 或 200 或 204 以外的任何内容请求,或者如果不使用那些必要的响应 header 进行响应。
    避免为问题中的案例触发预检的方法是:
  • 如果服务器不需要 Authorization请求 header ,而是依赖于嵌入在 POST 正文中的身份验证数据。请求或作为查询参数
  • 如果服务器不需要 POST body 要有Content-Type: application/json媒体类型,而是接受了 POST正文为 application/x-www-form-urlencoded带有一个名为 json 的参数(或其他)其值为 JSON 数据

  • 如何解决“Access-Control-Allow-Origin header 不能是通配符”问题

    I am getting another error message:

    The value of the 'Access-Control-Allow-Origin' header in the responsemust not be the wildcard '*' when the request's credentials mode is'include'. Origin 'http://127.0.0.1:3000' is therefore not allowedaccess. The credentials mode of requests initiated by theXMLHttpRequest is controlled by the withCredentials attribute.


    对于包含凭据的请求,如果 Access-Control-Allow-Origin 的值,浏览器将不会让您的前端 JavaScript 代码访问响应。响应头是 * .相反,这种情况下的值必须与您的前端代码的来源完全匹配, http://127.0.0.1:3000 .
    Credentialed requests and wildcards在 MDN HTTP 访问控制 (CORS) 文章中。
    如果您控制要向其发送请求的服务器,那么处理这种情况的常用方法是将服务器配置为采用 Origin 的值。请求 header ,并将其回显/反射(reflect)回 Access-Control-Allow-Origin 的值响应头;例如,使用 nginx:
    add_header Access-Control-Allow-Origin $http_origin
    但这只是一个例子;其他(网络)服务器系统提供类似的方法来回显原始值。

    I am using Chrome. I also tried using that Chrome CORS Plugin


    Chrome CORS 插件显然只是简单地注入(inject)了一个 Access-Control-Allow-Origin: *浏览器看到的响应中的 header 。如果插件更智能,它会做的是设置那个假的值 Access-Control-Allow-Origin前端 JavaScript 代码实际来源的响应 header , http://127.0.0.1:3000 .
    所以避免使用该插件,即使是为了测试。这只是一种分心。要测试您从服务器获得哪些响应而没有浏览器过滤它们,最好使用 curl -H如上。

    至于 fetch(…) 的前端 JavaScript 代码问题中的要求:
    headers.append('Access-Control-Allow-Origin', 'http://localhost:3000');
    headers.append('Access-Control-Allow-Credentials', 'true');
    删除这些行。 Access-Control-Allow-* header 是响应 header 。您永远不想在请求中发送它们。唯一的效果是触发浏览器进行预检。

    关于javascript - 请求的资源上不存在 'Access-Control-Allow-Origin' header —尝试从 REST API 获取数据时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43871637/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com