Docker 工兵:获得';“获取事件”&书信电报;url>&引用;导致网络错误响应:承诺被拒绝;码头工人之下
设置: 我是Sapper(以及web开发)的新手。 我一直在学习Sapper并尝试构建一个web应用程序,包括:Docker 工兵:获得';“获取事件”&书信电报;url>&引用;导致网络错误响应:承诺被拒绝;码头工人之下,docker,svelte,sapper,Docker,Svelte,Sapper,设置: 我是Sapper(以及web开发)的新手。 我一直在学习Sapper并尝试构建一个web应用程序,包括: 数据库服务器(mysql) 后端(beego) 前端(工兵) 它们中的每一个都使用docker compose进行停靠,我有一个用户定义的网络。比如: version: '3' services: db: networks: - fullstack_network ... api: networks: - fullstack_
version: '3'
services:
db:
networks:
- fullstack_network
...
api:
networks:
- fullstack_network
...
frontend:
environment:
# The env variable will be used as the base URL to the backend (api)
- API_ENDPOINT=http://api:8082
depends_on:
- api
networks:
- fullstack_network
...
networks:
fullstack_network:
问题:
在前端(已停靠),我有一个名为foo
的页面。单击页面时,我希望对返回JSON的后端API进行API调用
正如我一直试图实现的那样,我对preload函数进行API调用。
它总是抛出一个错误500:
未捕获(承诺中)TypeError:无法获取
我从控制台看到一条警告:
“的获取事件”http://api:8082/v1/foo“导致网络错误响应:承诺被拒绝
获得成功结果的唯一方法是刷新页面,这是不好的
注意:如果前端没有被停靠,我根本不会遇到这个错误
这是我的路线/foo.svelte
:
<script context="module">
import {API_ENDPOINT} from "../components/Config.js"
export async function preload(page, {env}) {
let api_endpoint = API_ENDPOINT;
if (env['API_ENDPOINT'] !== undefined) {
api_endpoint = env['API_ENDPOINT'];
}
let url = api_endpoint + "/v1/foo";
// when dockerized, the url is "http://api:8082/v1/foo"
// when it is not dockerized, the url is "http://localhost:8080/v1/foo", because I make the backend (api) accessible from the host machine.
const response = await this.fetch(url);
if (response.ok) {
const json = await response.json();
return {
results: json
};
} else {
throw new Error("Fetch foo failed!");
}
}
</script>
<script>
export let results;
</script>
<svelte:head>
<title>Foo</title>
</svelte:head>
<p>
This is the foo overview.
</p>
{#await results}
<p>fetching ...</p>
{:then results}
<pre>{JSON.stringify(results, null, 2)}</pre>
{:catch error}
<div class="error">Unable to fetch the data! <br/>
{error}
</div>
{/await}
从“./components/Config.js”导入{API_ENDPOINT}
导出异步函数预加载(第页,{env}){
设api_endpoint=api_endpoint;
if(env['API_ENDPOINT']!==未定义){
api_endpoint=env['api_endpoint'];
}
让url=api_endpoint+“/v1/foo”;
//停靠时,url为“http://api:8082/v1/foo"
//未停靠时,url为“http://localhost:8080/v1/foo,因为我使后端(api)可以从主机访问。
const response=wait this.fetch(url);
if(response.ok){
const json=await response.json();
返回{
结果:json
};
}否则{
抛出新错误(“获取foo失败!”);
}
}
出口结果;
福
这是foo概述。
{#等待结果}
获取
{:然后是结果}
{JSON.stringify(结果,null,2)}
{:捕获错误}
无法获取数据
{错误}
{/等待}
你能帮我找到根本原因和解决办法吗?感谢您对出现问题的原因作出解释。这似乎与苗条或赛珀无关。当您键入url
http://api:8082/v1/foo
在浏览器中,您是否可以获得所需的数据?如果不是,则表示在docker外部无法访问地址api:8082。谢谢!我重新阅读了预加载文档,预加载块中的代码可以在服务器或客户端浏览器中运行。当API调用在服务器上(docker容器内)运行时,http://api:8082
是可访问的,因为前端与后端api共享同一网络。这就解释了刷新页面(即按下F5按钮)的原因。当代码在浏览器上运行时,http://api:8082
不可访问。解决此问题的一种方法是为后端使用固定地址或FQDN,该地址或FQDN在docker容器内外均可访问。这似乎与Svelte或Sapper无关。当您键入urlhttp://api:8082/v1/foo
在浏览器中,您是否可以获得所需的数据?如果不是,则表示在docker外部无法访问地址api:8082。谢谢!我重新阅读了预加载文档,预加载块中的代码可以在服务器或客户端浏览器中运行。当API调用在服务器上(docker容器内)运行时,http://api:8082
是可访问的,因为前端与后端api共享同一网络。这就解释了刷新页面(即按下F5按钮)的原因。当代码在浏览器上运行时,http://api:8082
不可访问。解决此问题的一种方法是为后端使用固定地址或FQDN,该后端可在docker容器内外访问。