其实项目里在联调接口前,都会配置好代理,解决跨域
配置代理,是因为浏览器同源策略的保护,防止不同源(域、协议或端口)的网页之间进行恶意操作
而我们正常开发的时候,项目框架已经搭建好,前期的东西已经配置好,我们只要关注具体的业务,调接口联调即可
但是理解代理,知道如何解决跨域还是挺有必要的
假设项目刚创建好,需要联调接口,vue推荐使用axios,这里对于axios不过多解释,基本上大家都知道,是基于XMLHttpRequests进行了二次封装
<el-button @click="getlist">
获取数据
</el-button>
import axios from 'axios';
getlist(){
axios.get('http://localhost:5000/infolist').then(res=>{
response=>{
console.log('请求成功了',response.data);
},
error=>{
console.log('请求失败了',error.message);
}
})
}
报错中出现CORS,NO‘Access-Control-Allow-Origin’header,这个就是因为跨域了
假如我们的本地是http:localhost:8080
http:协议名
localhost:主机名
8080:端口号
假如服务器是http:localhost:5000
同源策略是只要有一个不一样,都是跨域。我们发送的请求服务器收到了,服务器也返回了,但是浏览器拦截了,出于同源策略的保护,浏览器没有返回给我们。
解决跨域最常见的几种办法:
1、cors 服务器携带特殊的响应头,需要后端配合
2、jsonp 借助script的src属性,引入外部资源的时候不受同源策略的限制,jsonp需要前后端一起配合,且只能解决get请求,解决不了post请求,delete请求,put请求,开发中用的少,但又是面试的时候特别喜欢问的,就是考你到底知不知道有这种解决跨域的方法
3、配置代理
代理服务器,与我们本地处于同一个端口号8080,本地发送的请求先经过代理服务器,由代理服务器去和后台的服务器请求数据
后台服务器返回的数据也是交由代理服务器,再由代理服务器返回给我们
为什么使用了代理服务器就能解决跨域,因为代理服务器虽然端口号是8080,后台服务器是5000,但是服务器与服务器之间传数据不需要ajax,ajax是前端技术。服务器之间是通过http请求,同源策略根本管不到两台服务器之间传数据。
配置代理的方法
1、nginx (要懂后端知识)
2、vue-cli借助脚手架开启代理
本文主要讲的就是第二种,vue官网-脚手架配置参考请戳这里
在项目的vue.config.js中
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
devServer: {
//代理可以写多个,代理不同的后端地址
proxy: {
"/api": {
target: "http://localhost:5000", // 将请求代理到后端的地址
changeOrigin: true,
pathRewrite: {
"^/api": "", // 重写路径,后端接受到的将不带/api
},
"/map": {
target: "http://localhost:6000", // 将请求代理到后端的地址
changeOrigin: true,
pathRewrite: {
"^/map": "", // 重写路径,后端接受到的将不带/map
},
},
},
},
});
页面中请求的地方也要改一下,1:加上/api 2:端口号改为自己的8080,因为已经走代理服务器了,代理服务器的端口就是8080
getlist(){
axios.get('http://localhost:8080/api/infolist').then(res=>{
response=>{
console.log('请求成功了',response.data);
},
error=>{
console.log('请求失败了',error.message);
}
})
}
但是项目中不会直接就这样请求数据,会对axios进行二次封装,创建axios实例的时候,根路径如果直接写成后台的服务器http:localhost:5000,这就是一个踩坑点了,我们已经通过代理服务器,所以我们要写的是
// 创建axios实例
const service = axios.create({
// axios中请求配置有baseURL选项,表示请求URL公共部分
baseURL: 'api',
timeout: 90000
})
备注–实际项目中的写法:
实际项目中会在src平级目录下新增.env.development和.env.production
以.env.developmen示例:
# 开发环境配置
ENV = 'development'
# xxx系统/开发环境
VUE_APP_BASE_API = '/dev-api'
# 路由懒加载
VUE_CLI_BABEL_TRANSPILE_MODULES = true
在vue.config.js中
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
devServer: {
//代理可以写多个,代理不同的后端地址
proxy: {
[process.env.VUE_APP_BASE_API]: {
target: defaultSettings.host,
changeOrigin: true,
pathRewrite: { [`^${process.env.VUE_APP_BASE_API}`]: '' },
},
},
});
在封装axios的js文件中
// 创建axios实例
const service = axios.create({
// axios中请求配置有baseURL选项,表示请求URL公共部分
baseURL: process.env.VUE_APP_BASE_API,
timeout: 90000
})
实际发送请求