小疑问?Nuxt服务端渲染为什么存在跨域呢?

986 阅读2分钟

你是否会有这样的疑问?服务端渲染明明是在服务端获取数据的,为什么会出现跨域问题?跨域不是主要出现在浏览器的吗?

就Nuxt来举例:

跨域问题:

Nuxt服务端渲染存在跨域问题的原因是因为在服务端渲染时,请求数据的域名与当前页面的域名不一致,导致浏览器的同源策略阻止了跨域请求。

具体来说,当浏览器发起一个跨域请求时,会先发送一个OPTIONS请求,该请求称为预检请求,用于询问服务器是否允许跨域请求。如果服务器允许跨域请求,则会返回一些特定的头部信息,告诉浏览器可以进行跨域请求。而在Nuxt服务端渲染中,由于请求是在服务端发起的,而不是在浏览器中发起的,所以浏览器的同源策略并不会阻止服务端发起跨域请求。但是,服务端发起的跨域请求仍然需要经过预检请求,如果服务器没有正确地设置跨域头部信息,就会导致预检请求失败,从而出现跨域问题。

另外,由于Nuxt服务端渲染是在Node.js环境下运行的,而Node.js的http模块默认不允许跨域请求。因此,如果在服务端使用了http模块发送跨域请求,也需要设置跨域头部信息,否则会出现跨域问题。

为了解决Nuxt服务端渲染的跨域问题,可以在服务器端设置:

module.exports = {
  serverMiddleware: [
    function (req, res, next) {
      res.setHeader('Access-Control-Allow-Origin', '*')
      next()
    }
  ]
}

这里的`Access-Control-Allow-Origin`头部信息设置为*表示允许任何域名访问,也可以设置为特定的域名。

另外,也可以使用Nuxt的插件@nuxtjs/proxy来解决跨域问题,该插件可以将服务端的请求转发到目标地址,并自动设置跨域头部信息。

1.下载axios和proxy代理

npm install @nuxtjs/axios @nuxtjs/proxy

export default {
  head: { ... },
  css: [],

  modules: [
    '@nuxtjs/axios',
  ],

  axios: {
    // 开启代理 (如果需要判断线上线下环境,可以通过 process.env.NODE_ENV !== 'production' 来判断)
    proxy: true,
    // 给请求 url 加个前缀 /api,如果这项不配置,则需要手动添加到请求链接前面
    // 如果是多个代理的时候,则不需要配置,走手动添加代理前缀
    prefix: '/api',
    // 跨域请求时是否需要使用凭证
    credentials: true
  },

  proxy: {
    '/api': {
      // 目标接口域
      target: 'http://localhost:3000',
      // 全局配置是否跨域
      changeOrigin: true,
      pathRewrite: {
        // 单个配置是否跨域
        // changeOrigin: true
        // 把 '/api' 替换成 '/',具体需要替换为 '' 还是 '/' 看自己习惯
        '^/api': '/'
      }
    }
  },

  build: {
    // 防止重复打包
    vendor: ['axios']
  }
}