axios 如何通过Nuxt.js服务器从Nuxt.js客户端发送请求并接收返回到客户端的响应

4xrmg8kj  于 2022-11-05  发布在  iOS
关注(0)|答案(2)|浏览(341)

我正在开发一个Vue.js应用程序,它只有前端(没有服务器),并向不同的API发送大量请求。原本非常简单的应用程序变得更加复杂。而且一些API也有问题,因为浏览器不接受CORS的响应。这就是为什么我试图测试,如果我可以将应用程序迁移到Nuxt.js。
我的方法如下(受comment的启发),但我希望,可能有一种更好的方法通过服务器从客户机发送请求。
页/测试页.vue

methods: {
  async sendRequest(testData) {
    const response = await axios.post('api', testData)
    // Here can I use the response on the page.
  }
}

nuxt.config.js

serverMiddleware: [
  { path: '/api', handler: '~/server-middleware/postRequestHandler.js' }
],

server-middleware/postRequestHandler.js

import axios from 'axios'

const configs = require('../store/config.js')

module.exports = function(req, res, next) {
  let body = ''

  req.on('data', (data) => {
    body += data
  })

  req.on('end', async () => {
    if (req.hasOwnProperty('originalUrl') && req.originalUrl === '/api') {
      const parsedBody = JSON.parse(body)

      // Send the request from the server.
      const response = await axios.post(
        configs.state().testUrl,
        body
      )

      req.body = response
    }
    next()
  })
}

中间件/test. js(请参见:(API: The Context

export default function(context) {
  // Universal keys
  const { store } = context
  // Server-side
  if (process.server) {
    const { req } = context
    store.body = req.body
  }
}

页面/api.vue

<template>
  {{ body }}
</template>
<script>
export default {
  middleware: 'test',
  computed: {
    body() {
      return this.$store.body
    }
  }
}
</script>

当用户在页面“test”上执行操作时,将启动方法“sendRequest()",然后请求“axios.post('api',testData)”将产生一个响应,其中包含页面“api”的HTML代码。然后我可以从HTML中提取JSON“body”。
我发现最后一步不是最佳的,但是我不知道如何只发送JSON而不是整个页面。但是我想,一定有更好的方法将数据发送给客户端。

u59ebvdq

u59ebvdq1#

有两种可能的解决方案:
1.代理(请参阅:(第10页)

  1. API(请参见:https://medium.com/@johnryancottam/running-nuxt-in-parallel-with-express-ffbd1feef83c

广告1.代理

代理服务器的配置如下所示:

  • nuxt.配置文件 *
module.exports = {
...
  modules: [
    '@nuxtjs/axios',
    '@nuxtjs/proxy'
  ],
  proxy: {
    '/proxy/packagist-search/': {
      target: 'https://packagist.org',
      pathRewrite: {
        '^/proxy/packagist-search/': '/search.json?q='
      },
      changeOrigin: true
    }
  },
  ...
}

通过代理的请求可能如下所示:

axios
  .get('/proxy/packagist-search/' + this.search.phpLibrary.searchPhrase)
  .then((response) => {
    console.log(
      'Could get the values packagist.org',
      response.data
    )
    }
  })
  .catch((e) => {
    console.log(
      'Could not get the values from packagist.org',
      e
    )
  })

广告2. API

在创建新的Nuxt.js应用时,选择 Express 作为项目的服务器端框架。

  • 服务器/索引.js*
...
app.post('/api/confluence', confluence.send)
app.use(nuxt.render)
...
  • 服务器/confluence.js*(简化版)
const axios = require('axios')
const config = require('../nuxt.config.js')

exports.send = function(req, res) {
  let body = ''
  let page = {}

  req.on('data', (data) => {
    body += data
  })

  req.on('end', async () => {
    const parsedBody = JSON.parse(body)
    try {
      page = await axios.get(
        config.api.confluence.url.api + ...,
        config.api.confluence.auth
      )
    } catch (e) {
      console.log('ERROR: ', e)
    }
  }

  res.json({
    page
  })
}

通过API的请求如下所示:

this.$axios
  .post('api/confluence', postData)
  .then((response) => {
    console.log('Wiki response: ', response.data)
  })
  .catch((e) => {
    console.log('Could not update the wiki page. ', e)
  })
dffbzjpn

dffbzjpn2#

现在使用nuxtjs3:
nuxtjs3 rc release
1.你有fetch或useFetch,不需要导入axios或其他库,什么是伟大的,自动解析身体,自动检测头
提取数据
1.你有中间件和服务器api在同一个应用程序上,你可以在查询上添加标题,隐藏例如令牌等
服务器层
这里在VUE文件I中的一个快速示例调用服务器API:

const { status } = await $fetch.raw( '/api/newsletter', { method: "POST", body: this.form.email } )
    .then( (response) => ({
        status: response.status,
    }) )
    .catch( (error) => ({
        status: error?.response?.status || 500,
    }) );

它将调用我的服务器上的一个方法,以初始化根目录上的服务器。我创建了一个名为server的文件夹,然后创建了一个名为api的文件夹,并创建了一个名为newsletter.ts的文件(我使用的是typescript),然后在此文件中:

export default defineEventHandler(async (event) => {
const {REST_API, MAILINGLIST_UNID, MAILINGLIST_TOKEN} = useRuntimeConfig();
const subscriber = await readBody(event);
console.log("url used for rest call" + REST_API);
console.log("token" + MAILINGLIST_TOKEN);
console.log("mailing list unid" + MAILINGLIST_UNID);
let recipientWebDTO = {
    email: subscriber,
    subscriptions: [{
        "mailingListUnid": MAILINGLIST_UNID
    }]
};
const {status} = await $fetch.raw(REST_API, {
    method: "POST",
    body: recipientWebDTO,
    headers: {
        Authorization: MAILINGLIST_TOKEN,
    },
}).then((response) => ({
    status: response.status,
}))
    .catch((error) => ({
        status: error?.response?.status || 500,
    }));
event.res.statusCode = status;
return "";
})

有什么好处?

  • REST_API,MAILING_LIST_UNID,MAILING_LIST_TOKEN不会在客户端上公开,甚至连newsletter.ts文件在调试浏览器上也不可用
  • 您只能在服务器端添加日志事件不公开API URL以避免某些攻击
  • 你不必创建一个新的后端只是为了隐藏一些关键令牌或数据

然后由您选择中间件路由或服务器API。您不必导入新的库,h3通过硝基嵌入nuxtjs3,并通过vuejs3获取
对于代理,您还发送了由h3提供代理:发送代理H3
当你在开发服务器和客户端同时构建(并且没有在配置文件中实现或配置),并且构建为o时,不要以静态方式部署你的项目(但是我认为你可以在静态中部署前端,在节点中部署服务器,我不知道)

相关问题