【vue】配置代理解决跨域详细篇--Access to XMLHttpRequest at ’http:xx‘ from origin’http:xx‘has been blocked by CORS

avatar
作者
筋斗云
阅读量:0

其实项目里在联调接口前,都会配置好代理,解决跨域

配置代理,是因为浏览器同源策略的保护,防止不同源(域、协议或端口)的网页之间进行恶意操作

而我们正常开发的时候,项目框架已经搭建好,前期的东西已经配置好,我们只要关注具体的业务,调接口联调即可

但是理解代理,知道如何解决跨域还是挺有必要的

假设项目刚创建好,需要联调接口,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 }) 

实际发送请求
在这里插入图片描述

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!