[英]CORS failing somewhere in Docker-Compose Stack w/NGINX - can't find it
CORS 絕對是最糟糕的。 我試圖在next.js
-> next.js
-> NGINX
docker-compose
-> clojure
一個 POST 請求失敗的 CORS。 我有以下錯誤消息,但沒有說明它來自堆棧中的哪個位置(是的!):
Cross-Origin Request Blocked:
The Same Origin Policy disallows reading the remote resource
at http://example.com/back/email.
(Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
axios error from PostRequest at endpt /email : Error: "Network Error"
所以...我將寫出請求觸及的每個部分,並嘗試表明它應該通過。 如果有人能找到此管道中請求失敗或 CORS 未正確打開的位置,請告訴我。 CORS 是最高階的反模式。
好的
我有一個前端dockerfile next.js
(進口的一點是, port 3000
暴露):
FROM node:10
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
EXPOSE 3000
CMD [ "npm", "start" ]
后端有一個用於clojure
的 dockerfile(暴露了port 4000
):
FROM java:8-alpine
WORKDIR /
COPY ./target/uberjar/ .
EXPOSE 4000
CMD java -jar clojure_play-0.1.0-SNAPSHOT-standalone.jar
這是docker-compose
文件,其中正確映射了端口3000
和4000
以及加載 NGINX 作為反向代理的webserver
服務:
version: '3'
services:
frontend:
build:
context: .
dockerfile: Dockerfile
container_name: frontend
restart: unless-stopped
ports:
- "3000:3000"
networks:
- app-network
backend:
build:
context: ./backend/clojure_play
dockerfile: Dockerfile
container_name: backend
restart: unless-stopped
ports:
- "4000:4000"
networks:
- app-network
webserver:
image: nginx:mainline-alpine
container_name: webserver
restart: unless-stopped
ports:
- "80:80"
volumes:
- web-root:/var/www/html
- ./nginx-conf:/etc/nginx/conf.d
depends_on:
- frontend
- backend
networks:
- app-network
volumes:
web-root:
driver: local
networks:
app-network:
driver: bridge
這是我的NGINX
配置。 請注意,我代理傳遞到我的 docker compose 中的網橋提供的服務名稱(每個都映射到適當的端口, 3000
或4000
)。 我對請求標頭也有點傻,但我正在嘗試盡可能多地打開它:
server {
listen 80;
listen [::]:80;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
# server_name example.com www.example.com;
# server_name localhost;
server_name example.me www.example.com;
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
#
# Custom headers and headers various browsers *should* be OK with but aren't
#
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
#
# Tell client that this pre-flight info is valid for 20 days
#
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
proxy_pass http://frontend:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /back/ {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
#
# Custom headers and headers various browsers *should* be OK with but aren't
#
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
#
# Tell client that this pre-flight info is valid for 20 days
#
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
proxy_pass http://backend:4000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
}
location ~ /.well-known/acme-challenge {
allow all;
root /var/www/html;
}
}
最后,我的后端clojure
應用程序有一個名為wrap-cors
的實用程序,它應該為我的站點提供 cors 支持:
(defn -main
"this is main"
[& args]
(println "hello there main")
(run-server
(wrap-cors
(wrap-json-body my-routes {:keywords? true :bigdecimals? true})
:access-control-allow-origin [#"http://www.example.me"]
:access-control-allow-methods [:get :put :post :delete]
)
{:port 4000})
#_(run-server my-routes {:port 8080})
)
就是這樣。
當我在next.js
前端發出請求時,我希望客戶端的計算機會向www.example.com/back/email
發出 http 請求,該請求將進入 NGINX 代理,點擊/back/
位置,發送/email
向我的clojure
服務器/email
,然后將返回 200。相反,我收到了上面的 CORS 錯誤。
有沒有人知道如何調試這個?
刪除所有位置標題上的重復設置。
添加以下代碼。
location / {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Accept,Content-Type';
}
在設置上述配置時,我能夠解決 CORS 錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.