React w/Kubernetes 部署的 API 给出了 cors 错误
Posted
技术标签:
【中文标题】React w/Kubernetes 部署的 API 给出了 cors 错误【英文标题】:React w/ Kubernetes deployed API giving cors error 【发布时间】:2021-01-04 17:42:08 【问题描述】:这与其他 cors 相关的问题不同
我正在 部署在 Digitalocean 上的 kubernetes 上的微服务上运行我的节点后端 API。我已经阅读了与此问题相关的所有博客/论坛,但没有找到任何解决方案(特别是与 Digitalocean 相关的解决方案)。
我无法通过在“localhost:3000”或 kubernetes 集群之外的任何地方运行的 React 应用程序连接到集群。
它给了我以下错误:
Access to XMLHttpRequest at 'http://cultor.dev/api/users/signin'
from origin 'http://localhost:3000' has been blocked by
CORS policy: Response to preflight request doesn't pass access
control check: Redirect is not allowed for a preflight request.
kubernetes 集群的负载均衡器正在监听 "cultor.dev",它在 /etc/hosts 中设置为本地域。 我可以使用 Postman 让它工作!
注意: 我也尝试过使用 cors 包,它无济于事。此外,如果我在我不想要的 kubernetes 集群内运行这个反应应用程序,它也可以正常工作。
Ingress nginx config(尝试使用官网提到的注解):
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-service
## this tells ingress to pick up the routing rules mentioned in this config
annotations:
nginx.ingress.kubernetes.io/default-backend: ingress-nginx-controller
kubernetes.io/ingress.class: nginx
## tells ingress to check for regex in the config file
nginx.ingress.kubernetes.io/use-regex: 'true'
# nginx.ingress.kubernetes.io/enable-cors: 'true'
# nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, OPTIONS"
# nginx.ingress.kubernetes.io/cors-allow-origin: "*"
# nginx.ingress.kubernetes.io/cors-max-age: 600
# certmanager.k8s.io/cluster-issuer: letsencrypt
# kubernetes.io/ingress.class: nginx
# service.beta.kubernetes.io/do-loadbalancer-enable-proxy-protocol: "true"
微服务配置之一(也尝试过 cors 包):
// APP SETTINGS
app.set('trust proxy', true);
app.use(json());
app.use((req, res, next) =>
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', '*');
res.header('Access-Control-Request-Headers', '*');
if (req.method === "OPTIONS")
res.header('Access-Control-Allow-Methods', '*');
return res.status(200).json();
next();
);
【问题讨论】:
您能否发布 Postman 请求的原始输出以及完整的 Ingress 配置。 【参考方案1】:好的,经过大量研究并在其他答案的帮助下,我做了以下事情:
-
我将对后端(从客户端)的请求更改为 https 而不是 http。这修复了错误
Redirect is not allowed for a preflight request
我更改了配置 ingress nginx 配置以摆脱错误multiple values in Access-Control-Allow-Origin
:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-service
annotations:
nginx.ingress.kubernetes.io/default-backend: ingress-nginx-controller
kubernetes.io/ingress.class: nginx
## tells ingress to check for regex in the config file
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/configuration-snippet: |
add_header Access-Control-Allow-Methods "POST, GET, OPTIONS";
add_header Access-Control-Allow-Credentials true;
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, OPTIONS"
我希望它也能帮助其他人。
【讨论】:
【参考方案2】:为什么要评论 cors 设置?
nginx.ingress.kubernetes.io/configuration-snippet: |
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Methods "POST, GET, OPTIONS";
add_header Access-Control-Allow-Credentials true;
GitHub 上的同样问题
【讨论】:
【参考方案3】:预检请求不允许重定向。
似乎发生了重定向。没有足够的信息来确定在哪里。我的猜测是您在 Ingress 上设置了 TLS,并且 http://cultor.dev/api/users/signin
被自动重定向到 https
。
【讨论】:
有办法检查吗?如何检查? 您的 Ingress 配置中是否有tls
指令?当您在浏览器中访问该页面时是https
?
是的,它在浏览器上显示带有红十字的 https。
这就是你的答案 - 删除 tls
指令,或向 https
提出请求。
我该怎么做?【参考方案4】:
CORS policy: Response to preflight request doesn't pass access
control check: Redirect is not allowed for a preflight request.
预检 CORS 请求实际上是浏览器向您的服务器发出的一个单独请求,以检查在响应中发回的访问控制标头是否会接受主请求。预检请求使用 HTTP OPTIONS
方法。我敢打赌,如果您为传入请求记录 req.method
,您将看到传入的 OPTIONS
请求。
当您收到这些预检请求之一时,您应该使用相应的 Access-Control-Allow-Origin
和 Access-Control-Allow-Headers
响应标头进行响应。
【讨论】:
以上是关于React w/Kubernetes 部署的 API 给出了 cors 错误的主要内容,如果未能解决你的问题,请参考以下文章