[Spring Cloud] (4)搭建Vue2与网关、微服务通信并配置跨域

文章目录

  • 前言
  • gatway
    • 网关跨域配置
    • 取消微服务跨域配置
  • 创建vue2项目
    • 准备一个原始vue2项目
      • 安装vue-router
      • 创建路由
      • vue.config.js配置修改
      • App.vue修改
    • 添加接口访问
      • 安装axios
      • 创建request.js
      • 创建index.js
      • 创建InfoApi.js
    • main.js
    • securityUtils.js
  • 前端登录界面
    • 登录
    • 消息提示框
  • 最终效果

前言

一个完整的项目都需要前后端,有些小伙伴会认为,为什么后端依然要学习前端的一些知识?只能说,技多不压身,也是一些必须的内容,因为你在学习的过程中,不免会使用到前端的东西。你总不能找个前端女朋友给你写测试demo吧?所以只能自力更生。。。
本文就从零搭建一个前端项目,以配合后端的各种拦截器的处理规则。(前端有些地方可能处理的不好,敬请见谅)
本文gateway,微服务,vue已开源到gitee
杉极简/gateway网关阶段学习

gatway

网关跨域配置

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
import org.springframework.web.util.pattern.PathPatternParser;@Configuration
public class CorsConfig {@Beanpublic CorsWebFilter corsFilter() {CorsConfiguration config = new CorsConfiguration();config.addAllowedMethod("*");config.addAllowedOrigin("*");config.addAllowedHeader("*");UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());source.registerCorsConfiguration("/**", config);return new CorsWebFilter(source);}
}

取消微服务跨域配置

注释删除微服务的跨域,否则会使跨域失效(网关与微服务不能同时开启跨域)
image.png

    @Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedOriginPatterns("*").allowedMethods("GET","HEAD","POST","DELETE","OPTIONS").allowCredentials(true).maxAge(3600).allowedHeaders("*");}

创建vue2项目

准备一个原始vue2项目

最初的应该是这样的
image.png

安装vue-router

npm install  vue-router@2.8.1

创建路由

image.png

import Router from 'vue-router'
import Vue from "vue";
import loginTest from "@/views/loginTest.vue";Vue.use(Router)const routes = [{path: '/',name: 'login',component: loginTest},
]const router = new Router({mode: 'history',base: process.env.BASE_URL,routes: routes
})export default router

vue.config.js配置修改

image.png
引入polyfill

 npm i node-polyfill-webpack-plugin

修改vue.config.js

const { defineConfig } = require('@vue/cli-service')
// 引入polyfill
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin')module.exports = defineConfig({transpileDependencies: true,// 引入polyfillconfigureWebpack: {plugins: [new NodePolyfillPlugin({})]},devServer: {client: {overlay: false}}
})

App.vue修改

image.png

<template><div id="app"><div class="version-switch"><button @click="switchVersion('/')">登录</button></div><router-view></router-view></div>
</template><script>export default {name: 'App',components: {},methods: {switchVersion(path) {this.$router.push(path);},}}
</script><style>#app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;/*color: #2c3e50;*/min-height: 100vh; /* 最小高度为视口高度,确保垂直居中 */}.version-switch {width: 100%; /* 宽度设置为100%,独占一整行 */height: 2%; /* 宽度设置为100%,独占一整行 */margin-top: 20px;margin-bottom: 20px;}.version-switch button {padding: 5px 10px;margin-right: 5px;justify-content: center; /* 水平居中 */}
</style>

添加接口访问

安装axios

npm install axios --save

创建request.js

image.png

import axios from 'axios'//引入axios
// 动态获取本机ip,作为连接后台服务的地址,但访问地址不能是localhost
// 为了灵活配置后台地址,后期需要更改为,配置文件指定字段决定优先使用配置ip还是自己生产的ip(如下)
const hostPort = document.location.host;
const hostData = hostPort.split(":")
const host = hostData[0];//axios.create能创造一个新的axios实例
const server = axios.create({baseURL: "http" + "://" + host + ":51001", //配置请求的urltimeout: 6000, //配置超时时间headers: {'Content-Type': "application/x-www-form-urlencoded",}, //配置请求头})/** 请求拦截器 **/
server.interceptors.request.use(function (request) {// 非白名单的请求都加上一个请求头return request;
}, function (error) {return Promise.reject(error);
});/** 响应拦截器 **/
server.interceptors.response.use(function (response) {return response.data;
}, function (error) {// axios请求服务器端发生错误的处理return Promise.reject(error);
});/*** 定义一个函数-用于接口* 利用我们封装好的request发送请求* @param url 后台请求地址* @param method 请求方法(get/post...)* @param obj 向后端传递参数数据* @returns AxiosPromise 后端接口返回数据*/
export function dataInterface(url, method, obj) {return server({url: url,method: method,params: obj})
}export default server

创建index.js

image.png

/*** HTTP 库* 存储所有请求*//** 节点测试接口 **/
import InfoApi from "@/api/InfoApi"export default {...InfoApi,
}

创建InfoApi.js

import {dataInterface} from "@/utils/request";export default {/** 系统登陆接口 **/login(obj) {return dataInterface("/auth/login","get", obj)},oneGetValue(obj){return dataInterface("/api-one/getValue", "get", obj)},twoGetValue(obj){return dataInterface("/api-two/getValue", "get", obj)},
}

main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import http from "@/api/index";
import securityUtils from "@/utils/securityUtils";Vue.config.productionTip = falseVue.prototype.$http = http;
Vue.prototype.$securityUtils = securityUtils;import MessageBox from './components/MessageBox.vue'Vue.component('MessageBox', MessageBox)// 将 MessageBox 组件挂载到 Vue.prototype 上
Vue.prototype.$message = function ({ message, duration, description }) {const MessageBoxComponent = Vue.extend(MessageBox)const instance = new MessageBoxComponent({propsData: { message, duration, description }})const vm = instance.$mount()document.body.appendChild(vm.$el)setTimeout(() => {document.body.removeChild(vm.$el)vm.$destroy()}, duration * 1000)
}// 在组件中使用 this.$message
// this.$message({ message: 'Hello world!', duration: 1.5, description: '' })new Vue({router,render: h => h(App),
}).$mount('#app')

securityUtils.js

image.png
securityUtils作为与后端网关通信的主要对象,之后的所有验证操作都在此处文件中处理。
对于不需要令牌头的请求,设置白名单放过指定的请求whiteList
对于普通的数据接口,需要增加令牌Authorization以通过后端的请求校验。

/** 全局变量配置-start **/// url白名单设置
const whiteList = ["/tick/auth/login",
]/** 全局变量配置-end **/export default {/*** 读取信息*/get(key) {return sessionStorage.getItem(key)},/*** 添加信息*/set(key, value) {sessionStorage.setItem(key, value)},/*** 登录之后进行处理*/loginDeal(token){this.set("token", token)},/*** gateway网关验证信息处理(请求头)*/gatewayRequest(config) {let key = true;whiteList.find(function (value) {if (value === config.url) {key = false;}});// 对非白名单请求进行处理if (key) {// 请求体数据let token = this.get("token")// 请求中增加tokenif (token) {config.headers.Authorization = token;}}return config;},}

前端登录界面

登录

image.png

<template><div><div><div class="login-form"><div><div><label>用户名:&nbsp;</label><input type="text" v-model="login.username"></div><div><label >密&nbsp;&nbsp;&nbsp;码:&nbsp;</label><input type="text" v-model="login.password"></div></div></div><div><button @click="loginApi">用户登录</button></div><div><div class="input-container2"><textarea class="my-input" v-model="token"/></div></div></div><div class="my-container"><button class="my-button" @click="oneValue">微服务一测试接口</button><div><textarea class="my-input" v-model="microserviceOneJsonFormData"></textarea></div><div><textarea class="my-input" v-model="microserviceOneJsonData"></textarea></div></div><div class="my-container"><button class="my-button" @click="twoValue">微服务二测试接口</button><div><textarea class="my-input" v-model="microserviceTwoJsonData"></textarea></div></div></div>
</template><script>export default {name: "loginTest",data() {return {token: "",login: {username: "fir",password: "123",},// 微服务节点一microserviceOneJsonFormData: {"msg": "普通的客户端消息",},microserviceOneJsonData: {},// 微服务节点二microserviceTwoJsonData: {},};},created() {this.jsonString();this.connection()},methods: {jsonString() {// 将JSON数据转换为字符串this.microserviceTwoJsonData = JSON.stringify(this.microserviceTwoJsonData, null, 2);this.microserviceOneJsonData = JSON.stringify(this.microserviceOneJsonData, null, 2);this.microserviceOneJsonFormData = JSON.stringify(this.microserviceOneJsonFormData, null, 2);},/*** 获取与后端建立通信的必备信息*/loginApi() {this.$http.login(this.login).then(res => {let code = res.codelet msg = res.msg// let data = res.dataif (code === 200) {this.$message({message: msg, duration: 1.5, description: ''})} else {this.$message({message: "错误", duration: 1.5, description: ''})}})},/** 微服务-1 **/oneValue() {// 在这里可以编写按钮被点击时需要执行的代码let data = JSON.parse(this.microserviceOneJsonFormData);this.$http.oneGetValue(data).then(res => {let msg = res.msglet replaceAfter = res;replaceAfter = JSON.stringify(replaceAfter, null, 2);this.microserviceOneJsonData = replaceAfter;this.$message({message: msg, duration: 1.5, description: ''})})},/** 微服务-2 **/twoValue() {this.$http.twoGetValue().then(res => {let msg = res.msglet replaceAfter = resreplaceAfter = JSON.stringify(replaceAfter, null, 2);this.microserviceTwoJsonData = replaceAfter;this.$message({message: msg, duration: 1.5, description: ''})})},},
}
</script><style scoped>/* 水平布局,且向左浮动 */
.login-form {margin-top: 40px;
}.login-input {display: flex;flex-direction: row;
}.login-form > div {float: left;margin-right: 10px;
}/* 全局安全痛惜参数-start */
.my-container {width: 100%;display: flex;justify-content: flex-start;flex-wrap: wrap;.input-container > label {flex: 1;}
}.my-container > button {align-self: flex-start;
}.my-container > .input-container {display: flex;flex-direction: column;align-items: center;
}.my-input {width: 300px; /* 设置输入框的宽度 */height: 200px; /* 设置输入框的高度 */border: 1px solid #ccc; /* 设置输入框的边框 */border-radius: 5px; /* 设置输入框的圆角 */padding: 5px; /* 设置输入框的内边距 */font-size: 14px; /* 设置输入框的字体大小 */color: white; /* 设置输入框的字体颜色为白色 */background-color: #434554; /* 设置输入框的背景色 */resize: vertical; /* 设置输入框垂直方向可自适应 */float: left; /* 将两个元素浮动在左侧 */box-sizing: border-box; /* 元素的内边距和边框不会增加元素的宽度 */
}.my-button {float: left; /* 将两个元素浮动在左侧 */box-sizing: border-box; /* 元素的内边距和边框不会增加元素的宽度 */
}
</style>

消息提示框

image.png

<template><div class="message-box"><div class="message-box__header">{{ message }}</div><div class="message-box__body">{{ description }}</div><button class="message-box__close" @click="close">X</button></div>
</template><script>
export default {name: "MessageBox",props: {message: { type: String, default: '' },duration: { type: Number, default: 1.5 },description: { type: String, default: '' },},methods: {close() {this.$emit('close')},},mounted() {setTimeout(() => {this.close()}, this.duration * 1000)},
}
</script><style scoped>
.message-box {position: fixed;top: 1%;left: 50%;transform: translateX(-50%);z-index: 9999;width: 300px;height: 20px;padding: 20px;background-color: #fff;box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
}.message-box__header {font-size: 16px;font-weight: bold;margin-bottom: 10px;
}.message-box__body {font-size: 14px;line-height: 1.5;margin-bottom: 20px;
}.message-box__close {position: absolute;top: 10px;right: 10px;width: 20px;height: 20px;padding: 0;border: none;background-color: transparent;cursor: pointer;font-size: 16px;font-weight: bold;color: #666;
}
</style>

最终效果

此时我们需要先登录,之后就可以正常访问微服务。
image.png此时如果不登陆就直接访问数据接口的话,则会提示登录过期,无法获取数据。
image.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/315220.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微信小程序使用echarts组件实现饼状统计图功能

微信小程序使用echarts组件实现饼状统计图功能 使用echarts实现在微信小程序中统计图的功能&#xff0c;具体的实现步骤思路可进我主页查看我的另一篇博文https://blog.csdn.net/weixin_45465881/article/details/138171153进行查看&#xff0c;本篇文章主要使用echarts组件实…

SpringBoot的自动装配原理

SpringBoot自动装配原理 SpringBoot的启动类上有一个注解&#xff1a;SpringBootApplication 。该注解是三个注解的复合注解。 1.SpringBootConfiguration 注解 点进SpringBootConfiguration 注解&#xff0c;可以发现其核心注解为Configuration注解&#xff1a; Configuration…

python文件 成绩分析

‘’文件score.txt中存储了学生的考试信息,内容如下 小明,98 小刚,90 小红,91 小王,98 小刘,80 请写代码,读取文件数据,并进行如下分析 最高分和最低分分别是多少&#xff1f;得最高分的学生有几个&#xff1f; 得最低分的学生有几个平均分是多少&#xff1f; ‘’’ def rea…

Web3技术解析:区块链在去中心化应用中的角色

引言 在过去几年中&#xff0c;Web3技术已经成为了互联网领域的一个热门话题。作为区块链技术的延伸&#xff0c;Web3不仅仅是数字货币的代名词&#xff0c;更是一个能够为各种应用提供去中心化解决方案的强大工具。本文将深入探讨区块链在Web3去中心化应用中的关键角色&#…

Python_AI库 Matplotlib的应用简例:绘制与保存折线图

本文默认读者已具备以下技能&#xff1a; 熟悉Python基础语法&#xff0c;以自行阅读python代码块熟悉Vscode或其它编辑工具的应用 在数据可视化领域&#xff0c;Matplotlib无疑是一个强大的工具。它允许我们创建各种静态、动态、交互式的可视化图形&#xff0c;帮助我们更好…

企业工厂如何逆风翻盘:VR全景打破多重桎梏

现阶段&#xff0c;制造业工厂面临的困境&#xff0c;就是用着上百万的设备&#xff0c;却赚着几毛钱的利润。传统的工厂参观方式也存在着很多的局限性&#xff0c;例如时间上不方便、不能实地参访、生产线具有隐患等&#xff0c;都会使得参观者不能深入地了解工厂的生产环境和…

Android Studio实现内容丰富的安卓养老平台

获取源码请点击文章末尾QQ名片联系&#xff0c;源码不免费&#xff0c;尊重创作&#xff0c;尊重劳动 158安卓养老 1.开发环境 后端用springboot框架&#xff0c;安卓的用android studio开发android stuido3.6 jak1.8 idea mysql tomcat 2.功能介绍 安卓端&#xff1a; 1.注册登…

实验7:路由冗余协议HSRP配置管理(课内实验以及解答)

实验目的及要求&#xff1a; 理解首跳冗余协议&#xff08;FHRP&#xff09;的工作原理&#xff0c;掌握热备份路由器协议 (HSRP)&#xff08;思科私有协议&#xff09;原理和配置。能够实现网络终端设备虚拟网关的配置和网络故障的灵活切换&#xff0c;完成相应网络的联通性测…

斐波那契数列

感谢大佬的光临各位&#xff0c;希望和大家一起进步&#xff0c;望得到你的三连&#xff0c;互三支持&#xff0c;一起进步 个人主页&#xff1a;LaNzikinh-CSDN博客 收入专栏:初阶数据结构_LaNzikinh篮子的博客-CSDN博客 文章目录 前言一.斐波那契数二.改循环三.尾递归总结 前…

智能外呼文书送达系统,智慧检务解决方案

在全民数字化改革中&#xff0c;司法体制改革不断推进的大背景下&#xff0c;合肥高新技术产业开发区人民检察院的内设机构改革已完成落地&#xff0c;刑事案件审查办理迎来了重大改变&#xff0c;需要检察官对现有办案方式方法做出相应的调整&#xff0c;将主要精力从大量的重…

初始计算机网络

TCP/IP TCP/IP模型 TCP/IP网络模型&#xff1a;对于不同设备之间的通信&#xff0c;就需要网络通信&#xff0c;而设备是多样性的&#xff0c;所以要兼容多种多样的设备&#xff0c;就协商出了一套通用的网络协议。 TCP/IP分层 这个网络协议是分层的&#xff0c;每一层都有…

【EI会议|投稿优惠】2024年机械应用与能源动力国际会议(ICMAEP 2024)

2024 International Conference on Mechanical Applications and Energy Power 一、大会信息 会议名称&#xff1a;2024年机械应用与能源动力国际会议 会议简称&#xff1a;ICMAEP 2024 收录检索&#xff1a;提交Ei Compendex,CPCI,CNKI,Google Scholar等 会议官网&#xff1a;…

【Linux系统编程】第九弹---权限管理操作(下)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、目录权限 2、粘滞位 总结 1、目录权限 首先提出一个问题&#xff0c;删除一个文件需要什么权限呢&#xff1f;&#xff1f…

基于 SpringCloud 的在线交易平台乐优商城的设计与实现(四)

第 4 章 数据库设计 4.1 数据库设计原则 4.2.数据库概念结构设计 4.3 数据库表设计 4.4.本章小结 前面内容请移步 基于 SpringCloud 的在线交易平台乐优商城的设计与实现&#xff08;三&#xff09; 相关免费源码资源 乐优商城 第 4 章 数据库设计 4.1 数据库设计原…

消息服务应用1——java项目使用websocket

在当前微服务项目中&#xff0c;由于业务模块众多&#xff0c;消息服务的使用场景变得异常活跃。而WebSocket由于其自身的可靠性强&#xff0c;实时性好&#xff0c;带宽占用更小的优势&#xff0c;在实时通讯应用场景中独占鳌头&#xff0c;加上HTML5标准的普及流行&#xff0…

记录些AI Agents设计模式和NL2SQL知识

吴恩达分享的四种 自我反思&#xff08;Reflection&#xff09;&#xff1a;可以自我修正&#xff1b;使用工具&#xff08;Tool Use&#xff09;&#xff1a;链接其他系统去做一些事情&#xff0c;比如把电脑里面的未归档文件做好归档&#xff1b;规划&#xff08;Planning&a…

2024年五一联赛数学建模思路+论文+代码+结果

一、竞赛时间 2024年5月1日10:00至2024年5月4日12:00(北京时间&#xff0c;24时计时法)。 二、报名时间 2024年4月7日00:00至2024年4月30日24:00(北京时间&#xff0c;24时计时法)。&#xff08;如受突发事情影响而导致系统注册报名推后&#xff0c;将另行通知&#xff09; …

应急行业的智能安全帽(高端)

前面介绍了低端、中端安全帽&#xff0c;接着再讲讲高端安全帽。做高端安全帽的企业非常少&#xff0c;估计一只手都数的出来。确实也和智能安全帽这个领域体量有关系&#xff0c;并且他有一个新的“劲敌”——智能眼镜从其他领域瓜分原属于他的市场&#xff0c;这些都是题外话…

【从后端日志文件中过滤出sql语句】

从后端日志文件中过滤出sql语句 why?思路日志文件的格式 结果 why? 为什么会有这种需求&#xff1f;&#xff0c;mysql数据不小心被删了完全可以从备份数据恢复&#xff0c;或者从binlog中恢复&#xff0c;但是如果前面这两种方法没办法处理&#xff08;没有备份数据库文件、…

分类神经网络2:ResNet模型复现

目录 ResNet网络架构 ResNet部分实现代码 ResNet网络架构 论文原址&#xff1a;https://arxiv.org/pdf/1512.03385.pdf 残差神经网络(ResNet)是由微软研究院的何恺明、张祥雨、任少卿、孙剑等人提出的&#xff0c;通过引入残差学习解决了深度网络训练中的退化问题&#xff…