Nuxt3 server功能说明

此文章仅作记录,就我的观察经验来说,不建议使用,仍然存在未修复的bug

本文内容如下

  1. 简述传统前后端分离项目如何发起请求
  2. 简述 nuxt3中 server/api和server/middleware
  3. 给出我实际开发的配置









传统前后端分离的请求

由于前端存在跨域问题,所以我们无论开发和部署时都面临跨域的配置,因此:

  • 开发时,使用devServer转发后端接口
  • 部署时,使用nginx转发后端接口

因此实际上,前端的请求是被拦截的,一般是拦截 /api ,实际的请求是到了服务端,如java端

browser → api 浏览器中页面切换、交互等
nuxt2 → api SSR渲染









nuxt3的做法

  • nuxt本身就是用于SSR的框架,在nuxt2中,我们虽然配置了node端渲染时,请求后端接口,然而,在浏览器端,实际上还是被nginx拦截去直接请求了服务端,这种情况下,在开发时,实际上依然是需要配置devSaerver
  • 因此,nuxt3中,nuxt3的做法是,所有的请求发送到nuxt3 server端,然后由nuxt3 server端去请求后端的真实接口

原本:
browser → api

nuxt3:
browser → nuxt3 server → api


@/server目录

使用该功能前,请先安装 h3

npm install -S h3

@/server/api

这个目录可以添加一个nuxt3 server的接口,页面可以直接通过 $fetch(‘/api/xx’)来访问
举个例子:

// @/server/api/hello.js
import {defineEventHandler} from 'h3';


defineEventHandler((e)=>{
	retrun {
	     code: 0.
	     message: 'ok!'
	}    
})

此时即可通过 http://localhost:3000/api/hello 访问该接口,可以看到结果

 {
	 code: 0.
	 message: 'ok!'
}    

而在页面中,可以通过 $fetch('/api/hello') 访问该接口





@/server/middleware

这个实际上就相当于 express中的middleware,对所有api进行拦截的,如果middleware中直接return了,则不再请求 server/api 中对应的请求,这里可以看一个官网的例子

// @/server/middleware/log.js

import {defineMiddleware} from 'h3‘

export default defineMiddleware(e=>{
	console.log('New Request Access');
	console.log(e.req.url);
})

这个middleware实际上在每次向 nuxt3 server发送请求时,都会进入并打印日志





实际项目中的运用

  1. 首先明确一点,nuxt3中的跨域,实际上是通过 nuxt3 server进行的,因此,我们通过nuxt3 server转发所有对服务端的请求,并在 nuxt3 server中,携带用户身份参数token
// @/server/middleware/apiProxy.js

import {defineMiddleware, useBody, useCookies, useMethod, useQuery} from 'h3'
import {API_BASE, BACKEND_URL} from "../../config";
// 这里的
// API_BASE = "/api“”
// BACKEND_URL = "http://localhost:8080"  指向了后端服务


// 拦截api操作,转发后端接口
export default defineMiddleware(async (e) => {
    if (e.req.url.startsWith(API_BASE)) {
        const url = BACKEND_URL + e.req.url;
        const method = useMethod(e);
        const query = useQuery(e);
        const headers = e.req.headers;
        const cookies = useCookies(e);
        const token = cookies['token'];
        if (!token || !token.length) {
            delete headers['token'];
        }

        headers['token'] = cookies['token'];
        let body = null;

        if ('GET' !== method.toUpperCase()) {
            body = await useBody(e)
        }

        return $fetch(url, {
            method,
            params: query,
            headers,
            body
        })
    }
})



Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐