部署Nuxt+Express+MongoDB应用时无法获取数据库数据问题求助
问题概述
部署Web应用10天,先后在Heroku、DigitalOcean平台调试未解决问题,技术栈为前端Nuxt、后端Express.js、数据库MongoDB。修复Nuxt端口与host配置后,出现无法从数据库获取数据的问题,暂不确定是数据库连接问题还是Express API配置问题。
相关配置代码
Nuxt配置
export default { ssr: false, head: { titleTemplate: 'Lokazz', title: 'Lokazz', meta: [ { charset: 'utf-8' }, { name: 'viewport', content: 'width=device-width, initial-scale=1' }, { hid: 'description', name: 'description', content: 'Lokazz' } ], link: [ { rel: 'stylesheet', href: 'https://fonts.googleapis.com/css?family=Work+Sans:300,400,500,600,700&subset=latin-ext' } ] }, css: [ 'swiper/dist/css/swiper.css', '~/static/fonts/Linearicons/Font/demo-files/demo.css', '~/static/fonts/font-awesome/css/font-awesome.css', '~/static/css/bootstrap.min.css', '~/assets/scss/style.scss' ], plugins: [ { src: '~plugins/vueliate.js', ssr: false }, { src: '~/plugins/swiper-plugin.js', ssr: false }, { src: '~/plugins/vue-notification.js', ssr: false }, { src: '~/plugins/axios.js'}, { src: '~/plugins/lazyLoad.js', ssr: false }, { src: '~/plugins/mask.js', ssr: false }, { src: '~/plugins/toastr.js', ssr: false }, ], buildModules: [ '@nuxtjs/vuetify', '@nuxtjs/style-resources', 'cookie-universal-nuxt' ], styleResources: { scss: './assets/scss/env.scss' }, modules: ['@nuxtjs/axios', 'nuxt-i18n','vue-sweetalert2/nuxt', '@nuxtjs/auth-next', "bootstrap-vue/nuxt"], bootstrapVue: { bootstrapCSS: false, bootstrapVueCSS: false, }, i18n: { locales: [ { code: 'en', file: 'en.json' }, ], strategy: 'no_prefix', fallbackLocale: 'en', lazy: true, defaultLocale: 'en', langDir: 'lang/locales/' }, router: { linkActiveClass: '', linkExactActiveClass: 'active', }, server: { port: 8080, host: '0.0.0.0' }, auth: { strategies: { local: { token: { property: "token", global: true, }, redirect: { "login": "/account/login", "logout": "/", "home": "/page/ajouter-produit", "callback": false }, endpoints: { login: { url: "/login", method: "post" }, logout: false, user:false } } } }, };
package.json配置
{ "name": "martfury_vue", "version": "1.3.0", "description": "Martfury - Multi-purpose Ecomerce template with vuejs", "author": "nouthemes", "private": true, "scripts": { "dev": "nuxt", "build": "nuxt build", "start": "nuxt start", "generate": "nuxt generate" }, "config": { "nuxt": { "host": "0.0.0.0", "port": "8080" } }, }
repository.js配置
import Cookies from 'js-cookie'; import axios from 'axios'; const token = Cookies.get('id_token'); const baseDomain = 'https://lokazzfullapp-8t7ec.ondigitalocean.app'; export const customHeaders = { 'Content-Type': 'application/json', Accept: 'application/json' }; export const baseUrl = `${baseDomain}`; export default axios.create({ baseUrl, headers: customHeaders }); export const serializeQuery = query => { return Object.keys(query) .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(query[key])}`) .join('&'); };
本地可用API调用示例
import Repository, { serializeQuery } from '~/repositories/Repository.js'; import { baseUrl } from '~/repositories/Repository'; import axios from 'axios' const url = baseUrl; export const actions = { async getProducts({ commit }, payload) { const reponse = await axios.get(url) .then(response => { commit('setProducts', response.data); return response.data; }) .catch(error => ({ error: JSON.stringify(error) })); return reponse; }, }
Express入口文件index.js
const express = require('express'); const bodyParser = require('body-parser'); const mongoose = require('mongoose') const cors = require('cors'); //const url = 'mongodb://localhost:27017/lokazz' const url = 'mongodb+srv://lokazz:zaki123456@cluster0.hsd8d.mongodb.net/lokazz?retryWrites=true&w=majority' const jwt = require('jsonwebtoken') const con = mongoose.connection mongoose.connect(url, {useNewUrlParser:true}).then(()=>{ const app = express(); // middlleware app.use(express.json()) app.use(cors()); //products routes const products = require('./product/product.router'); app.use('/', products) //users routes const users = require('./user/user.router'); app.use('/', users) const port = process.env.PORT || 5000; app.listen(port, () => console.log(`Server started on port ${port}`)); }).catch(error => console.log(error.reason)); con.on('open', () => { console.log('connected...') })
目录结构

报错信息
ebd1ecd.js:2 TypeError: Cannot read properties of undefined (reading 'username') at f.<anonymous> (c88240c.js:1) at f.t._render (ebd1ecd.js:2) at f.r (ebd1ecd.js:2) at wn.get (ebd1ecd.js:2) at new wn (ebd1ecd.js:2) at t (ebd1ecd.js:2) at f.In.$mount (ebd1ecd.js:2) at init (ebd1ecd.js:2) at ebd1ecd.js:2 at v (ebd1ecd.js:2)
排查解决方案
1. 排查MongoDB连接问题
- 到部署平台后台查看服务日志,看是否有MongoDB连接失败的报错。如果有:
- 检查MongoDB Atlas的IP白名单是否放开部署平台的出口IP,测试阶段可临时设置允许所有IP访问
- 确认数据库用户名、密码、集群连接地址与Atlas配置一致
- 如果日志打印了
connected...,说明MongoDB连接正常。
2. 排查Express服务启动问题
- 查看部署日志是否有打印
Server started on port X,如果没有打印,说明Express服务没有正常启动 - 你当前package.json的启动命令只启动了Nuxt服务,没有启动Express服务,这是核心问题之一:
- 安装concurrently工具:
npm install concurrently --save - 修改package.json的scripts配置,同步启动两个服务(替换为你实际的Express入口文件路径):
"scripts": { "dev": "concurrently \"nuxt\" \"node ./server/index.js\"", "build": "nuxt build", "start": "concurrently \"nuxt start\" \"node ./server/index.js\"", "generate": "nuxt generate" } - 安装concurrently工具:
- 直接用浏览器/Postman访问你的接口地址(即repository.js中的baseDomain),如果能拿到返回数据,说明后端服务正常,问题出在前端。
3. 排查前端问题
- 你当前的报错是因为接口请求失败后返回了错误对象,但代码没有做错误判断,直接读取了不存在的属性。修改API请求代码,增加日志和错误判断:
async getProducts({ commit }, payload) { try { const response = await axios.get(url) console.log('接口返回数据:', response.data) commit('setProducts', response.data); return response.data; } catch(error) { console.error('接口请求失败:', error) return { error: error.message } } }
- 你封装的axios实例配置项大小写错误,
baseUrl要改为baseURL,否则封装的实例会请求到错误地址:
export default axios.create({ baseURL: baseUrl, headers: customHeaders });
- 如果Nuxt和Express分开部署,要确认repository.js中的baseDomain是Express服务的部署地址,不是Nuxt前端的地址。如果同容器部署,要配置Nuxt代理转发API请求到Express的端口,避免跨域问题。
内容的提问来源于stack exchange,提问作者Sb Zakaria
相关产品推荐
相关产品推荐

