其实项目里在联调接口前,都会配置好代理,解决跨域
配置代理,是因为浏览器同源策略的保护,防止不同源(域、协议或端口)的网页之间进行恶意操作
而我们正常开发的时候,项目框架已经搭建好,前期的东西已经配置好,我们只要关注具体的业务,调接口联调即可
但是理解代理,知道如何解决跨域还是挺有必要的
假设项目刚创建好,需要联调接口,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 })
实际发送请求