Nuxt获取数据踩坑记

今天搞Nuxt获取数据踩了一整天的坑,在此记下

首先是这样一个获取数据的页面

<template>
  <div class="article-detail">
    <article>{{ article }}</article>

    <hr />

    <div class="comment">{{ comment }}</div>
  </div>
</template>

<script setup lang="ts">
const route = useRoute();
const id = route.params.id;

const url = 'https://xiaojiju.com/api/article/' + id;

const { data: article, refresh } = await useFetch(url);

const res = await useAsyncData(() => $fetch('https://xiaojiju.com/api/comment/article/' + id));

const comment = ref(res.data.value).value;
onMounted(() => {
  refresh();
});
</script>

<style scoped lang="scss"></style>

useAsyncData这里一直不显示数据,而且没有任何报错。

然后试了一下第三方接口,发现代码是没错的,那么就是接口的问题了,然后本地启动了一个服务器代码改为

<template>
  <div class="article-detail">
    <article>{{ article }}</article>

    <hr />

    <div class="comment">{{ comment }}</div>
  </div>
</template>

<script setup lang="ts">
const route = useRoute();
const id = route.params.id;

const url = 'https://xiaojiju.com/api/article/' + id;

const { data: article, refresh } = await useFetch(url);

const res = await useAsyncData(() => $fetch('http://localhost:3000/api/comment/article/' + id));

const comment = ref(res.data.value).value;
onMounted(() => {
  refresh();
});
</script>

<style scoped lang="scss"></style>

发现还是一样没有任何报错,这时候就要暴露出错误才行,而Nuxt$fetch支持错误回调,然后改为

<template>
  <div class="article-detail">
    <article>{{ article }}</article>

    <hr />

    <div class="comment">{{ comment }}</div>
  </div>
</template>

<script setup lang="ts">
const route = useRoute();
const id = route.params.id;

const url = 'https://xiaojiju.com/api/article/' + id;

const { data: article, refresh } = await useFetch(url);

const res = await useAsyncData(() =>
  $fetch('http://localhost:3000/api/comment/article/' + id, {
    onRequestError(ctx) {
      console.log('onRequestError', ctx);
      return Promise.resolve();
    },
  }),
);

const comment = ref(res.data.value).value;
onMounted(() => {
  refresh();
});
</script>

<style scoped lang="scss"></style>

运行后报错:

    onRequestError {
      request: 'http://localhost:3000/api/comment/article/1',
      options: { baseURL: '/', onRequestError: [Function: onRequestError] },
      response: undefined,
      error: TypeError: fetch failed
          at Object.processResponse (node:internal/deps/undici/undici:6254:34)
          at node:internal/deps/undici/undici:6579:42
          at node:internal/process/task_queues:140:7
          at AsyncResource.runInAsyncScope (node:async_hooks:203:9)
          at AsyncResource.runMicrotask (node:internal/process/task_queues:137:8)
          at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
        cause: Error: connect ECONNREFUSED ::1:3000
            at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1246:16) {
          errno: -61,
          code: 'ECONNREFUSED',
          syscall: 'connect',
          address: '::1',
          port: 3000
        }
      }
    }

connect ECONNREFUSED ::1:3000 可以看出Nuxt是不支持localhost的,然后改为127.0.0.1

<template>
  <div class="article-detail">
    <article>{{ article }}</article>

    <hr />

    <div class="comment">{{ comment }}</div>
  </div>
</template>

<script setup lang="ts">
const route = useRoute();
const id = route.params.id;

const url = 'https://xiaojiju.com/api/article/' + id;

const { data: article, refresh } = await useFetch(url);

const res = await useAsyncData(() =>
  $fetch('http://127.0.0.1:3000/api/comment/article/' + id, {
    onRequestError(ctx) {
      console.log('onRequestError', ctx);
      return Promise.resolve();
    },
  }),
);

const comment = ref(res.data.value).value;
onMounted(() => {
  refresh();
});
</script>

<style scoped lang="scss"></style>

运行后果然就能获取到了,但是替换为线上代码后还是获取失败

会报这样一段错unable to verify the first certificate,那么证明不是接口的问题

然后搜索了一下,发现是ssl证书不齐的原因,缺少了中间证书。

缺少中间证书的话在浏览器上打开是没问题的,但是通过nodejs去访问的话就会报错了。

然后打开服务器部署的cert.pem文件一看,里面只有一段-----BEGIN CERTIFICATE-----,而我记得之前下载证书文件cert.pem里面是2段-----BEGIN CERTIFICATE-----的,怀疑是这个原因,然后把下载的文件替换上去并重启Nginx,运行后果然就好了。

评论

0 / 800
全部评论()