在与SSR和代理一起使用nuxt时出现cors问题

时间:2020-10-25 22:12:26

标签: vue.js cors nuxt.js

我想用 nuxt 创建一个简单的愿望清单(娱乐项目) 这个想法很简单,用户将指向他想要项目的链接添加到主页(例如:https://www.amazon.fr/Bracelet-ethnique-multicolore-pierres-aventurine/dp/B088FNK7WS?pd_rd_w=VcswS&pf_rd_p=93b57529-44d6-414c-8e38-22f57431b7bd&pf_rd_r=F71JXZXPJQFHJR7E6ZCB&pd_rd_r=5c6a3226-b724-44f0-9c7c-1f7d75b21c00&pd_rd_wg=AJYnZ),链接存储到数组中,等等。 为了获得更好的视觉效果,我想根据链接的打开图数据(如果有)预填充商品名称并显示该商品的图片,为此,我找到了此插件:https://metascraper.js.org#/?id=usage(很好),以抓取我定位的页面的元数据。

我的问题是以下: 当我做一个简单的this.$axios.$get(link)时,我遇到了cors问题(请求的资源上没有No **'Access-Control-Allow-Origin'标头**)。经过一番研究,我发现此错误是由于服务器端渲染,需要使用代理来解决。 但是使用 @ nuxt / proxy 需要为每个网站定义一个 proxy (例如:'/amazon/': { target: 'https://amazon.com/', pathRewrite: { '^/amazon/': '' } }

或者,我需要从用户放入其愿望清单的任何链接中删除数据。我仍然可以使用 @ nuxt / proxy 还是需要更复杂的解决方案?

// test function to scrap data

const metascraper = require('metascraper')([
    require('metascraper-description')(),
    require('metascraper-image')(),
    require('metascraper-title')()
  ])
async mounted() {
      const url = "https://website.com"
      const content = await this.$axios.$get(url)
      console.log(await metascraper({ html: content, url: 'https://website.com' }))
 }

编辑: 非常感谢 MAS 我对他的解决方案做了一些调整,以使其可以与nuxt一起使用:

meta-scraper.js

import axios from 'axios'

const url = require('url')
const metascraper = require('metascraper')([
  require('metascraper-description')(),
  require('metascraper-image')(),
  require('metascraper-title')()
])

export default async function(req, res, next) {
  // parse querydata from url (nuxt don't give req.query)
  let queryData = url.parse(req.url, true).query

  // retrieve data from axios
  const content = await axios.get(queryData.target)

  // scrap data from content data and url
  const result = await metascraper({ html: content.data, url: queryData.target })

  // stringify result end send it with res.end (nuxt don't provide res.send or res.json)
  await res.end(JSON.stringify(result))
}

1 个答案:

答案 0 :(得分:0)

此错误实际上是浏览器安全功能,当您尝试从其他来源访问资源时,会触发该错误,请阅读更多here

要解决此问题,只需从服务器端触发剪贴请求,就可以使服务器充当代理。由于您使用的是nuxt,因此可以通过server-middleware轻松实现这一目标,因此可以创建自定义API,例如: / api / meta-scraper?target = http://www.amazon.com ... ,您可以从那里获取所需的元数据。请参见下面的示例代码。

nuxt.config.js

export default {
  serverMiddleware: [
    { path: '/api/meta-scraper', handler: '~/api/meta-scraper.js' }
  ]
}

〜/ api / meta-scapper.js

export default function (req, res, next) {
  // req is the Node.js http request object
  console.log(req)

  // res is the Node.js http response object
  // use metascraper here to scrap metadata

 const content = await axios.get(req.params.target)
 const result = await metascraper({ html: content, url: req.params.target })
 
 return res.send(result);
}

〜/ some-page.vue

async asyncData({ $axios }) {
  try {
    const result = await $axios.$get('/api/meta-scraper', {
      params: {
        target: 'https://amazon.com'
      }
    });
    console.log(result); // scrapped meta
  } catch (error) {
    console.log(error)
  }
},

希望我有所帮助!