V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
vczyh
V2EX  ›  程序员

Nextjs 如何访问后端服务的 API 以及如何跨域?

  •  
  •   vczyh · 2023-05-03 14:50:01 +08:00 · 3619 次点击
    这是一个创建于 598 天前的主题,其中的信息可能已经有所发展或是发生改变。

    React 新手,在学习 Next ,请教大家两个问题。

    1.Next 如何访问后端服务的 API ? 第一种是直接访问后端 API 。 另一种是访问 Next API Router ,API Router 中再访问后端 API 。 请问最佳实践是那种?

    2.Next 如何跨域?

    看文章都是通过 API Router ? 还有通过 next.config.js

      async rewrites() {
        return [
          {source: '/apis/:path*', destination: 'http://127.0.0.1:80/:path*'}
        ]
      }
    

    但是这样的话,GET 请求正常,POST 请求提示超时。请问如何解决?

    15 条回复    2023-05-05 14:11:50 +08:00
    dayeye2006199
        1
    dayeye2006199  
       2023-05-03 15:02:36 +08:00   ❤️ 1
    > 1.Next 如何访问后端服务的 API ? 第一种是直接访问后端 API 。 另一种是访问 Next API Router ,API Router 中再访问后端 API 。 请问最佳实践是那种?

    你如果只做 CSR ,普通 react 里面怎么访问的就怎么访问(例如写在 useEffect 里面的 fetch )。
    你做 SSG 或者 SSR ,那就写在 getStaticProps 或者 getServerSideProps 里面。

    api route 你看作一个普通的后端就可以了。如果 api route 单纯做一个转发,没必要通过这个额外的一层。除非你在里面还有一些别的逻辑(例如数据变换,动态修改头文件之类的)。

    > 2.Next 如何跨域?
    跨域是后端的事情。你需要后端给你的 response 头里面,包含允许跨域的信息。这个和前端没有太大的关系。

    你给的那个例子是一个转发的例子,就是让客户端觉得自己在访问 /apis/* 这个路径,实际通过 API routes 转发到其他的地址,来达到欺骗客户端的作用。
    rocmax
        2
    rocmax  
       2023-05-03 16:56:13 +08:00 via Android
    能在服务端获取数据的尽量服务端渲染后发给客户端。需要响应用户操作获取数据的访问 API
    vczyh
        3
    vczyh  
    OP
       2023-05-03 17:34:07 +08:00 via iPhone
    @dayeye2006199 谢谢大佬的耐心解答,我之前习惯用 Vue 的 dev server 跨域了。后端不适配的话,我本地起一个 server 代理一下吧。
    amlee
        4
    amlee  
       2023-05-03 17:35:13 +08:00
    能直接访问就直接访问呀。
    访问 api router 是因为服务端没有跨域支持,然后用 nextjs 的 api 对服务端做一个反代,这样就避免跨域了。
    至于 op 说的的 post 超时,这描述太模糊了吧。请求有没有到达后端?后端的路径上有没有处理 post ?
    vczyh
        5
    vczyh  
    OP
       2023-05-03 19:48:33 +08:00 via iPhone
    @amlee 这个没有到达后端,后端接口没问题,Get 请求正常。
    um1ng
        6
    um1ng  
       2023-05-03 20:43:25 +08:00
    写一个 server 服务,服务调服务,就不会跨域了,会用到这个

    ```
    import { createProxyMiddleware } from 'http-proxy-middleware'
    ```
    vczyh
        7
    vczyh  
    OP
       2023-05-03 21:00:49 +08:00 via iPhone
    @um1ng 我也准备用这个,感谢大佬
    unco020511
        8
    unco020511  
       2023-05-04 10:26:48 +08:00
    跨域是服务端的事
    vczyh
        9
    vczyh  
    OP
       2023-05-04 11:12:41 +08:00
    @unco020511 主要是开发阶段前端也可以解决一下,起一个代理服务器就可以。

    const express = require('express');
    const {createProxyMiddleware} = require('http-proxy-middleware')

    let app = express()

    app.all('*', (req, res, next) => {
    res.header('access-control-allow-origin', "*")
    res.header('access-control-allow-credentials', 'true')
    res.header('access-control-allow-methods', '*')
    res.header('access-control-allow-headers', '*')
    if (req.method.toUpperCase() == 'OPTIONS') {
    res.send(200)
    } else {
    next()
    }
    })

    app.use(
    '/apis',
    createProxyMiddleware({
    target: 'http://localhost:80',
    pathRewrite: {'^/apis': ''},
    changeOrigin: true,
    }));


    app.listen(4000)
    heishu
        10
    heishu  
       2023-05-04 14:05:11 +08:00
    get 都能通,post 不通?试试 postman 能不能跑通 post 呢
    lizy0329
        11
    lizy0329  
       2023-05-04 15:15:17 +08:00   ❤️ 1
    为什么能够问出这么 SX 的问题?有这个时间发帖,还不如看多几遍文档
    vczyh
        12
    vczyh  
    OP
       2023-05-04 18:58:28 +08:00 via iPhone
    @lizy0329 不愿意回答混蛋,需要你回答了?
    vczyh
        13
    vczyh  
    OP
       2023-05-04 19:34:35 +08:00 via iPhone
    @heishu 可以的
    amlee
        14
    amlee  
       2023-05-05 10:31:47 +08:00
    @vczyh 是不是你的 nextjs 项目里的路由,和 rewrites 里面的路由有冲突?请求在 nextjs 被处理了,就没有被发往目标服务。

    信息还是太少了
    vczyh
        15
    vczyh  
    OP
       2023-05-05 14:11:50 +08:00
    @amlee 这个有可能,我现在没用 nextjs rewrite 了,有时间我再看一下,感谢你的回复。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2508 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 19ms · UTC 02:57 · PVG 10:57 · LAX 18:57 · JFK 21:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.