我正在为API和前端使用不同的Docker容器。
frontend:
image: <my_frontend_image>
ports:
- "3000:3000"
api:
restart: always
build: ./<my_api_folder>
ports:
- "9002:9002"
在API方面,我有发送电子邮件的端点:
/emails/custom
在前端,我正在尝试向此端点发送请求:
$.ajax({
url: "http://api:9002/api/emails/custom",
dataType: "json",
type: "POST"
...
但它不起作用。看起来它再次向FrontEnd容器发送请求。
这里有什么问题?
更新: 也许这个问题在某种程度上与我的nginx配置有关:
location / {
# Define the location of the proxy server to send the request to
# Web it's a name of docker container with frontend.
proxy_pass http://frontend:3000;
# Redefine the header fields that NGINX sends to the upstream server
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Define the maximum file size on file uploads
client_max_body_size 5M;
}
# Setup communication with API container.
location /api {
rewrite "^/api/(.*)$" /$1 break;
proxy_pass http://api:9002;
proxy_redirect off;
proxy_set_header Host $host;
}
答案 0 :(得分:2)
您正尝试从浏览器外部访问api服务,而不是从可以访问api主机名的前端容器中访问。端口转发由docker完成,所以外部需要命中主机。例如:http://localhost:9002
(例如,如果你使用docker for mac)
可以找到类似的问题/答案here
答案 1 :(得分:1)
我更仔细地研究了你的问题。你不能做你想做的事情,因为浏览器总是使用本地env来发出ajax请求,并且在那个env“api”不存在的情况下,它看看它自己的hosts文件而找不到它,最后失败。
您需要更新您的前端代码,以便根据它的位置提出要求。
var url = document.location.protocol + "//" + document.location.hostname + ":9002";
var api = url + "/api/emails/custom"
$.ajax({
url: api,
dataType: "json",
type: "get",
});
}
您还可以在本地主机文件中正确解析“api”到IP地址,但我认为这是更明智的解决方案。我还制作了工作版here:
注意:我从POST更改为GET请求。
答案 2 :(得分:0)
嗯,问题在于JS URL中的最终/
。
它只是通过替换:
url: "http://api:9002/api/emails/custom",
与
url: "http://api:9002/api/emails/custom/",
另一件可能会改进的事情 - 主机名,正如@Marko所说。
答案 3 :(得分:0)
var url = document.location.protocol +“ //” + document.location.hostname +“:9002”; 这对我也适用。 但是我很好奇我们是否可以使用容器名称。