依然是设置项目根目录的 vue.config.js
对其配置中的 devServer.proxy
进行设置:
module.exports = {
devServer: {
open: true,
port: 8888,
proxy: {
'/api': {
// API服务器的地址
target: 'https://shop.ruan.work/',
// 如果是https接口,需要配置这个参数
secure: true,
// 是否跨域
changeOrigin: true
// 重写路径 比如'/api/aaa/ccc'重写为'/aaa/ccc'
// pathRewrite: {
// '^/api': ''
// }
}
}
}
}
官方文档:https://cli.vuejs.org/zh/config/#devserver-proxy
这种方式能实现跨域的原理是:
我们在使用vue-cli
脚手架工具开发项目的时候,其实 脚手架工具 启动了一个 本地node
服务,这也是为什么我们前端开发时的预览地址一般是:http://localhost:8888/(假设是这个地址) 的原因。不然的话,我们预览页面的地址应该是一个本地文件,比如类似这种:file:///Users/ss/Desktop/Test/1.html
如果我们的接口地址是 /api/user
,如果不进行特殊设置,那么 ajax
请求的地址就是: http://localhost:8888/api/user
,也就是访问的是我们的脚手架工具为我们提供的本地 node
服务器,如果我们设置了代理,那么我们的本地 Node
服务器接收到了请求会转发到对应的第三方服务端接口。
关于跨域
跨域产生的原因是:浏览器的同源策略。也就是说:是浏览器限制了请求,所以产生了跨域问题。而服务器与服务器之前的请求是没有跨域问题的。
这时候,我们可能会产生疑问,我们之前学习的解决跨域问题,一般会需要服务端配合,比如配置响应头的 Access-Control-Allow-origin
项。这个要从CORS
原理说起,具体可以参考阮一峰老师的文章:跨域资源共享 CORS 详解。
看完阮一峰老师的跨域资源共享 CORS 详解,其实我们可以明白,其实在确定请求跨不跨域、请求允不允许跨域,浏览器在做鉴定的时候,会在请求头中携带 Origin
项,然后根据服务端的响应头中的 Access-Control-*
项来鉴定的。也就是说,服务端是在需要的时候配合浏览器鉴定是不是跨域的。但是如果发起请求方,在请求之前不去鉴定是否跨域,那也就没有跨域问题了,比如:两台服务器之前发送请求的时候,比如我们可以用 两个node
服务试一下:
// s1.js
// 引入核心模块
const http = require('http');
// 创建服务器
const ser = http.createServer();
// 为服务器绑定request事件 表示当用户的请求发送到的时候触发
// 回调函数的参数说明:
// 参数1:发起请求的客户端的信息
// 参数2:服务端处理响应的相关参数和方法
ser.on('request', function (request, response) {
console.log(request);
console.log(response);
// 设置响应编码,防止乱码的出现
response.setHeader('Content-Type', 'text/html;charset=utf-8');
// 结束响应
response.end('Hwllo World');
});
// 设置服务器监听的端口
ser.listen('3000', '127.0.0.1', function(){
});
// s2.js
// 引入核心模块
const http = require('http')
// 发送的配置信息
const options = {
hostname: '127.0.0.1',
port: 3000,
path: '/',
method: 'GET',
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
}
// 发送请求
const req = http.request(options, function (res) {
console.log(`状态码: ${res.statusCode}`)
console.log(`响应头: ${JSON.stringify(res.headers)}`)
res.setEncoding('utf8')
res.on('data', (chunk) => {
console.log(`响应主体: ${chunk}`)
})
res.on('end', () => {
console.log('响应中已无数据')
})
})
req.on('error', (e) => {
console.error(`请求遇到问题: ${e.message}`)
})
// 将数据写入请求主体。
req.write('')
req.end()
这时,我们用 s2.js
去请求 s1.js
中的内容,是不会出现跨域问题的。