你是否会有这样的疑问?服务端渲染明明是在服务端获取数据的,为什么会出现跨域问题?跨域不是主要出现在浏览器的吗?
就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']
}
}