Nuxt ssr asyncData axios 请求不适用于页面重新加载

时间:2020-12-22 14:59:32

标签: docker axios nuxt.js server-side-rendering

在寻找解决方案 5-6 小时后,我开始放弃。我有一个包含 docker、node 和 nuxt 的项目。我想在 FB 上共享元标记,为此,我需要 SSR && vue-meta,而对于 vue-meta,我需要 asyncData。

它适用于不同的 api!

async asyncData({ params, $axios, error }) {
  const product = await $axios.$get(`https://api.nuxtjs.dev/posts/1`);
  return { product };
},

当我使用 nuxt 路由导航到此处时它正在工作,但是如果我重新加载页面(就在此处),那么我会从 nuxt ssr 收到 RuntimeError。

所以真正的问题是我在 LOCALHOST 上重新加载页面时出现运行时错误

async asyncData({ params, $axios, error }) {
  //axios knows the api
  //http://localhost:8080/ 
  const product = await $axios.$get(`products/${params.id}`);
  return { product };
},

如果我使用 Axios 尝试此操作,则会出现此错误:

Cannot read property 'data' of undefined

如果我用@nuxt/http 尝试这个,我就会得到这个错误

request to http://localhost:8080/products/some-id failed, reason: connect ECONNREFUSED 127.0.0.1:8080

我认为问题是当我在此页面上强制重新加载时,我无法在本地主机上发出请求,但我不知道为什么以及如何解决它。

我的 nuxt-config.js

export default {
  // Disable server-side rendering (https://go.nuxtjs.dev/ssr-mode)
  // ssr: false,

  // Global page headers (https://go.nuxtjs.dev/config-head)
  head: {
    title: '',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: '' }
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
      { rel: 'preconnect', href: 'https://fonts.gstatic.com' },
      { rel: 'stylesheet', href: 'https://fonts.googleapis.com/css2?family=Josefin+Sans:wght@300;400;600&display=swap' },
    ]
  },

  // Global CSS (https://go.nuxtjs.dev/config-css)
  css: [
    '@/assets/scss/styles.scss',
    // '~node_modules/bootstrap/dist/css/bootstrap.css',
    // '~node_modules/bootstrap-vue/dist/bootstrap-vue.css',
  ],

  // Plugins to run before rendering page (https://go.nuxtjs.dev/config-plugins)
  plugins: [
    '~/plugins/notifier',
    '~/plugins/axios',
    '~/plugins/dateFilter',
    '~/plugins/loading',
  ],

  // Auto import components (https://go.nuxtjs.dev/config-components)
  components: true,

  // Modules for dev and build (recommended) (https://go.nuxtjs.dev/config-modules)
  buildModules: [
    'nuxt-lazysizes', //https://github.com/ivodolenc/nuxt-lazysizes
    '@aceforth/nuxt-optimized-images', //https://github.com/juliomrqz/nuxt-optimized-images //only build
  ],

  // Modules (https://go.nuxtjs.dev/config-modules)
  modules: [
    '@nuxtjs/axios',
    '@nuxtjs/auth',
    '@nuxtjs/style-resources',
    'nuxt-i18n',
    'bootstrap-vue/nuxt',
    '@nuxt/http',
  ],

  styleResources: {
    scss: [
      // './assets/scss/*.scss',
      '@/assets/scss/_variables.scss',
      '@/node_modules/bootstrap/scss/_functions.scss',
      '@/node_modules/bootstrap/scss/_variables.scss',
      '@/node_modules/bootstrap/scss/mixins/_breakpoints.scss',
    ]
  },

  bootstrapVue: {
    bootstrapCSS: false,
    bootstrapVueCSS: false,
    icons: false,
  },

  axios: {
    // baseURL: ``, //built by docker compose from API_PORT && API_HOST variables
  },

  auth: {
    strategies: {
      local: {
        endpoints: {
          login: { url: '/auth/login', method: 'post', propertyName: 'token' },
          logout: false,
          user: { url: '/auth/user', method: 'get', propertyName: 'user' },
        },
      }
    },
    redirect: {
      login: '/login',
      logout: '/',
      callback: '/login',
      home: '/admin/products',
    },
  },

  // Build Configuration (https://go.nuxtjs.dev/config-build)
  build: {
    // babel: {
    //   compact: true,
    // },
  },

  router: {
    extendRoutes(routes, resolve) {
      routes.push(
        {
          name: 'product-edit',
          path: '/admin/products/edit/:id',
          component: 'pages/admin/products/add.vue',
        },
        {
          name: 'product-image-upload',
          path: '/admin/products/product-image-upload/:id',
          component: 'pages/admin/products/product-image-upload.vue',
        },
        {
          name: 'gallery-image-upload',
          path: '/admin/gallery-image-upload',
          component: 'pages/admin/gallery-image-upload.vue',
        },
      );
    }
  },

  env: {
    baseUrl: `${process.env.BASE_URL}`,
    imagePath: `${process.env.BASE_URL}:${process.env.API_PORT}/uploads`,
  },

  publicRuntimeConfig: {
    baseUrl: `${process.env.BASE_URL}`,
    imagePath: `${process.env.BASE_URL}:${process.env.API_PORT}/uploads`,
  },

  loading: '~/components/LoadingBar.vue',

  i18n: {
    locales: [
      { code: 'en', iso: 'en-US', file: 'en.js' },
      { code: 'hu', iso: 'hu-HU', file: 'hu.js' },
      { code: 'de', iso: 'de-DE', file: 'de.js' },
    ],
    defaultLocale: 'en',
    lazy: true,
    langDir: '/i18n/',
    parsePages: false,
    vueI18n: {
      fallbackLocale: 'en',
    },
    detectBrowserLanguage: {
      useCookie: true,
      cookieKey: 'i18n_redirected',
    },
    seo: false,
    vueI18nLoader: true,
    strategy: 'no_prefix',
  },

  lazySizes: {
    extendAssetUrls: {
      img: 'data-src',
      source: 'data-srcset',
      // Component with custom props
      AppImage: ['source-md-url', 'image-url'],
    },
  },

  optimizedImages: {
    inlineImageLimit: 1000,
    handleImages: ['jpeg', 'png', 'svg', 'webp', 'gif'],
    optimizeImages: false,
    optimizeImagesInDev: false,
    defaultImageLoader: 'img-loader',
    mozjpeg: {
      quality: 80,
    },
    optipng: {
      optimizationLevel: 3,
    },
    pngquant: false,
    gifsicle: {
      interlaced: true,
      optimizationLevel: 3,
    },
    svgo: {
      // enable/disable svgo plugins here
    },
    webp: {
      preset: 'default',
      quality: 75,
    },
  },
};

我的 docker-compose.yml

version: '3'
services:
  server:
    build:
      context: ./server
    env_file: .env
    expose:
      - $SERVER_PORT
    ports:
      - $SERVER_PORT:$SERVER_PORT
    volumes:
      - ./server:/usr/app
      - /usr/app/node_modules
  client:
    build:
      context: ./client
    env_file: .env
    environment:
      NUXT_HOST: 0.0.0.0
      NUXT_PORT: $CLIENT_PORT
      API_HOST: 0.0.0.0
      API_PORT: $SERVER_PORT
      BASE_URL: $BASE_URL
    volumes:
      - ./client:/usr/app
      - /usr/app/node_modules
    expose:
      - $CLIENT_PORT
    ports:
      - $CLIENT_PORT:$CLIENT_PORT

更新:如果我在没有 Docker 的情况下开始我的 nuxt 项目,那么一切正常,但这对我来说不是解决方案:D

1 个答案:

答案 0 :(得分:1)

我已经解决了我的问题。我不得不使用 nginx 代理作为容器和一些 nuxt 配置。

  // https://axios.nuxtjs.org/options/
  privateRuntimeConfig: {
    axios: {
      baseURL: 'http://nginx/api' // name of the docker proxy
    }
  },