从SvelteKit SSR访问localhost在升级到Node 18后突然失效。

huangapple go评论133阅读模式
英文:

Accessing localhost from SvelteKit SSR is suddenly broken after upgrading to Node 18

问题

我有一个在localhost:3000上运行的SvelteKit网站,以及一个在localhost:8000上运行的Django API。SvelteKit网站通过访问localhost:8000与API进行通信,既在SSR中,也在客户端中,这一直都运行得很好,直到今天。

突然间,这不再起作用了,当尝试从SSR发出对API的请求时,控制台会显示以下错误:

TypeError: fetch failed
    at fetch (/Users/kevin/Workspace/project_name/node_modules/.pnpm/undici@5.22.1/node_modules/undici/index.js:109:13)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Promise.all (index 2)
    at async fetchUserMiddleware (/Users/kevin/Workspace/project_name/src/middleware.ts:59:5)
    at async copyCookieValues (/Users/kevin/Workspace/project_name/src/middleware.ts:21:10)
    at async redirectMiddleware (/Users/kevin/Workspace/project_name/src/middleware.ts:16:10)
    at async /Users/kevin/Workspace/project_name/node_modules/.pnpm/@sentry+sveltekit@7.56.0_@sveltejs+kit@1.20.4_svelte@3.59.2/node_modules/@sentry/sveltekit/cjs/server/handle.js:111:19 {
  cause: Error: connect ECONNREFUSED ::1:8000
      at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1494:16)
      at TCPConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17) {
    errno: -61,
    code: 'ECONNREFUSED',
    syscall: 'connect',
    address: '::1',
    port: 8000
  }
}

我没有进行任何代码更改,但我最近运行了brew upgrade,并且我更新了pnpm。我正在运行Ventura 13.4.1,没有使用Docker或类似的东西。

当我手动在浏览器中访问localhost:8000,或者通过像RapidAPI这样的API工具访问时,一切都正常工作,没有问题。来自SvelteKit的来自浏览器的请求也正常工作,只有来自SSR的请求不起作用。

当我将SvelteKit网站更改为对127.0.0.1:8000发出请求而不是localhost:8000时,SSR请求再次起作用。所以我有了一个解决方案,但我想知道到底发生了什么。什么突然改变了,如何使其再次工作?

将代码还原到旧版本不会有任何不同。正如我所说,上周五最后一次在项目上工作时,这仍然可以正常工作,但是两天后突然出现了此错误,而没有更改代码。

编辑:我最近还从Node 16升级到了Node 18。将其降级回16可以解决问题。为什么Node 18会导致此问题,如何使其再次工作?

英文:

I have a SvelteKit website that I run on localhost:3000, and a Django API that I run on localhost:8000. The SvelteKit website talks to the API by accessing localhost:8000, both in SSR and in the client, and this has always worked perfectly fine. Until today.

All of a sudden this no longer works and I get this error in console when trying to make a request to the API from SSR:

TypeError: fetch failed
    at fetch (/Users/kevin/Workspace/project_name/node_modules/.pnpm/undici@5.22.1/node_modules/undici/index.js:109:13)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Promise.all (index 2)
    at async fetchUserMiddleware (/Users/kevin/Workspace/project_name/src/middleware.ts:59:5)
    at async copyCookieValues (/Users/kevin/Workspace/project_name/src/middleware.ts:21:10)
    at async redirectMiddleware (/Users/kevin/Workspace/project_name/src/middleware.ts:16:10)
    at async /Users/kevin/Workspace/project_name/node_modules/.pnpm/@sentry+sveltekit@7.56.0_@sveltejs+kit@1.20.4_svelte@3.59.2/node_modules/@sentry/sveltekit/cjs/server/handle.js:111:19 {
  cause: Error: connect ECONNREFUSED ::1:8000
      at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1494:16)
      at TCPConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17) {
    errno: -61,
    code: 'ECONNREFUSED',
    syscall: 'connect',
    address: '::1',
    port: 8000
  }
}

I have made no code changes, but I did recently run brew upgrade, and I updated pnpm. I'm running Ventura 13.4.1, and I'm not using Docker or anything like that.

When I manually access localhost:8000 in the browser, or via an API tool like RapidAPI, it all works perfectly normal, no problem. Requests from SvelteKit from the browser also work fine, only the ones from SSR are not working.

When I change my SvelteKit website to make requests to 127.0.0.1:8000 instead of localhost:8000, then SSR requests work again. So I have a solution, but I'd like to know what the hell is going on. What suddenly changed and how can I make it work again?

Reverting the code to an older version makes no difference. Like I said, this used to work perfectly fine last time I worked on the project last Friday, and now two days later all of a sudden it gives this error with no changes in the code.

Edit: I also recently updated from Node 16 to Node 18. Downgrading back to 16 fixes it. Why does Node 18 break this and how do I make it work again?

答案1

得分: 1

Ok, 显然在 Node 17 中有一个更改,改变了 localhost 解析的顺序,请参见 https://github.com/nodejs/undici/issues/1602。Django 默认不侦听 IPv6。所以我可以始终在 IPv6 上启动 Django,或者只是暂时将 localhost 更改为 127.0.0.1,我现在选择了后者。

编辑:

第三个选项是在 hooks.server.ts 中包含以下代码:

import dns from "node:dns";
dns.setDefaultResultOrder("ipv4first");
英文:

Ok, apparently there was a change in Node 17 that changes the order of what localhost resolves into, see https://github.com/nodejs/undici/issues/1602. Django by default doesn't listen to IPv6. So I could either always start Django on IPv6, or just change localhost to 127.0.0.1, which I've gone with for now.

Edit:

A third option is to include this code in hooks.server.ts:

import dns from "node:dns";
dns.setDefaultResultOrder("ipv4first");

huangapple
  • 本文由 发表于 2023年6月26日 04:09:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/76552226.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定