如何从同一本地网络上的不同机器/IP 访问 FastAPI 后端?

2024-12-23 08:43:00
admin
原创
174
摘要:问题描述:FastAPI 后端和 Next.js 前端都在 上运行localost。在同一台计算机上,前端使用 进行 API 调用没有任何问题。但是,在同一fetch网络上的另一台计算机(例如 )上,前端可以运行,但其 API 调用不再起作用。192.168.x.x我曾尝试使用代理作为 next.js,但仍然...

问题描述:

FastAPI 后端和 Next.js 前端都在 上运行localost。在同一台计算机上,前端使用 进行 API 调用没有任何问题。但是,在同一fetch网络上的另一台计算机(例如 )上,前端可以运行,但其 API 调用不再起作用。192.168.x.x

我曾尝试使用代理作为 next.js,但仍然不起作用。

前端:


export default function People({setPerson}:PeopleProps)  {
 const fetcher = async (url:string) => await axios.get(url).then((res) => res.data);
 const { data, error, isLoading } = useSWR(`${process.env.NEXT_PUBLIC_API}/people`, fetcher);
  if (error) return <div>"Failed to load..."</div>;
  return (
      <>
        {isLoading? "Loading..." :data.map((person: Person) =>
        <div key={person.id}> {person.name} </div>)}
     </> 
  )
 }

Next.js 应用env.local在启动时加载该文件,其中包含:
NEXT_PUBLIC_API=http://locahost:20002

后端:

rom typing import List
from fastapi import APIRouter, Depends
from ..utils.db import get_session as db
from sqlmodel import Session, select
from ..schemas.person import Person, PersonRead
router = APIRouter()

@router.get("/people", response_model = List[PersonRead])
async def get_people(sess: Session = Depends(db)):
    res = sess.exec(select(Person)).all()
    return res 

前端运行:npm run dev,并输出

ready - started server on 0.0.0.0:3000, url: http://localhost:3000

后端运行:uvicorn hogar_api.main:app --port=20002 --host=0.0.0.0 --reload,并输出:

INFO:     Uvicorn running on http://0.0.0.0:20002 (Press CTRL+C to quit)

http://localhost:3000 当我在同一台机器上打开浏览器时,列表Person就会显示在屏幕上。

当我在同一网络http://192.168.x.x:3000 上的另一台机器上打开浏览器时,收到“无法加载...”消息。

当我在任一机器上打开 FastAPI swagger 文档时,文档都正确显示,并且所有端点都按预期工作。

CORS 如下所示:

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

origins = [
    "http://localhost:3000",
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

解决方案 1:

host标志设置为0.0.0.0

要从同一网络上的不同机器/IP(而不是运行服务器的本地机器)访问 FastAPI 后端,您需要确保将host标志设置为0.0.0.0。IP 地址0.0.0.0表示本地机器上的所有hostIPv4 地址。如果有两个 IP 地址,例如192.168.10.210.1.2.5,并且 上运行的服务器host在 上侦听0.0.0.0,则可以通过这两个 IP 访问它。例如,通过命令行界面:

uvicorn main:app --host 0.0.0.0 --port 8000

或者,以编程方式:

if __name__ == '__main__':
    uvicorn.run(app, host='0.0.0.0', port=8000)

请注意,RFC 1122 禁止0.0.0.0将其用作 IPv4 中的目标地址,而仅允许将其用作源地址,这意味着您不能http://0.0.0.0:8000在 Web 浏览器的地址栏中键入地址并期望它能正常工作。您应该改用本地计算机的 IPv4 地址之一,例如http://192.168.10.2:8000(或者,如果您在运行服务器的同一台本地计算机上测试 API,则可以使用http://127.0.0.1:8000http://localhost:8000)。

调整防火墙设置

您可能还需要调整防火墙允许外部访问您指定的网络port,方法是为 Python 创建入站防火墙规则。在 Windows 上,当允许程序(在本例中为 Python)通过 Windows 防火墙进行通信时,通常会自动创建此规则,默认情况下,这将允许任何 port网络上的流量(对于 TCP 和 UDP 连接)。

调整 CORS 设置

此外,如果您的前端正在监听来自后端的单独IP 地址和/或端口号,请确保已启用CORS并正确配置,如此答案和此答案中所述。例如:

origins = ['http://localhost:3000','http://192.168.178.23:3000']

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

使用 JavaScript 发出 HTTP 请求

最后,请查看此答案和此答案fetch,了解如何在从前端发出 JavaScript 请求时使用正确的来源/URL 。简而言之,在您的 JavaScript 异步请求中,您应该使用您在 Web 浏览器地址栏中输入的相同port域名(但使用后端服务器正在监听的号码)。例如,如果后端和前端服务器都在监听相同的 IP 地址和端口号,例如 — 例如192.168.178.23:8000使用时就是这种情况Jinja2Templates— 您可以通过在浏览器的地址栏中输入指向前端页面的 URL 来访问前端,例如http://192.168.178.23:8000/fetch请求应如下所示:

fetch('http://192.168.178.23:8000/people', {...

为方便起见,在上述情况下(即,当后端和前端都在同一台计算机上运行并在同一台计算机上监听时port),您可以使用相对路径,如上面链接的答案中所建议的那样。请注意,如果您在同一台计算机上本地测试应用程序,而不是在 LAN 上的另一台计算机上测试应用程序,而是使用或访问前端/后端,则这两个是不同的域/来源。因此,如果您在浏览器的地址栏中输入以访问前端页面,则不应使用例如发出请求,因为您会收到 CORS 错误(例如)。您应该使用,反之亦然。127.0.0.1`localhosthttp://127.0.0.1:8000/fetchfetch('http://localhost:8000/people'Access to fetch at [...] from origin [...] has been blocked by CORS policy...`fetch('http://127.0.0.1:8000/people'

否则,如果前端与后端origin 不同(有关更多详细信息,请参阅此答案origin),则应将其添加到后端 CORS 设置中的来源列表中(请参阅上面的示例)。

解决方案 2:

这个问题困扰了我好几天 - 我在 Mac 上使用 fastapi/uvicorn,使用 Python 3.9。

当将 uvicorn 主机设置为 0.0.0.0 时,启动后我检查发现它只绑定到 TCP 127.0.0.1:

sudo lsof -PiTCP -sTCP:LISTEN

所以我深入研究了 uvicorn 代码,解决方案在这个文件中:/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/uvicorn/config.py

只需将其:sock.bind((self.host, self.port)) 更改为:sock.bind(('0.0.0.0', self.port))

完成此项更改后,我重新启动了 uvicorn,并且可以从网络上的任何机器访问该页面。

希望这对某人有帮助!

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用