一、完美解决Vue2.0+Axios开发生产环境跨域问题
由于博主主要是做后端开发和自动化运维的,因此,前端基本面向同学和搜索引擎编程...这次彻底搞出了一个简洁优雅的Vue和Axios配合的跨域方案,适合开发环境和生产环境!
(1)在config/index.js中配置开发环境跨域
proxyTable: {
'/api': {
target: 'https://211.64.32.228:8899/',
secure: false,
changeOrigin: true,
pathRewrite: {
'^/api': ''
},
headers: {
Referer: 'https://211.64.32.228:8899'
}
}
}
(2)在main.js中配置自动选择
import axios from 'axios'
import QS from 'qs'
Vue.prototype.$axios = axios
Vue.prototype.$qs = QS
Vue.prototype.baseUrl = process.env.NODE_ENV === "production" ? "https://211.64.32.228:8899" : "/api"
(3)在Vue文件中使用Axios
this.axios({
method: 'post',
url: this.baseUrl + '/helloworld',
data: {},
headers: {}
}).then((response) => {
// do some
}).catch((error) => {
// do some
});
(4)SpringBoot配置允许跨域
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration
public class CorsConfig {
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig());
return new CorsFilter(source);
}
}
二、SpringBoot中AES+Base64加解密用户登录凭据
这年头,md5是能反解的,再老也不能掉牙呀..
import org.apache.tomcat.util.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
// 使用方法:
// PasswordUtil.Encrypt(String)
// PasswordUtil.Decrypt(String)
public class PasswordUtil {
// openssl rand -hex 16
private static String salt = "38350e78e96b83e894b59cc9953af122";
public static String Encrypt(String password) throws Exception {
byte[] raw = salt.getBytes(StandardCharsets.UTF_8);
SecretKeySpec sRawSpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, sRawSpec);
byte[] encrypted = cipher.doFinal(password.getBytes(StandardCharsets.UTF_8));
return new Base64().encodeToString(encrypted);
}
public static String Decrypt(String password) throws Exception{
byte[] raw = salt.getBytes(StandardCharsets.UTF_8);
SecretKeySpec sRawSpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, sRawSpec);
byte[] encrypted = new Base64().decode(password);
byte[] original = cipher.doFinal(encrypted);
return new String(original, StandardCharsets.UTF_8);
}
}
三、纯CSS自定义超简洁文件上传控件input
主要是解决自定义CSS样式问题和Vue上传文件的问题...注释就不写了,静下心来稍微一看就懂!
{{uploadTips}}
四、Vuex最佳实践
(1)定义store/index.js,事实上应该事先模块化,但是我太懒了。
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const state = {
token: ''
};
const getters = {
getToken(state) {
return state.token
}
};
const mutations = {
setToken(state, token) {
state.token = token
}
};
const actions = {
commitToken({commit}, token) {
return commit('setToken', token)
}
};
const store = new Vuex.Store(
{
state,
getters,
mutations,
actions
}
);
export default store;
(2)在main.js中引用
import store from './store'
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: {App},
template: ' ',
store
})
(3)在Vue组件中引用
this.$store.dispatch('commitToken', value); // 向Store中存储数据
this.$store.getters.getToken; // 读取Store中的数据
五、Vue-router跳转
然而,官方文档是写的很明确的,但是我懒得翻官方文档...
this.$router.push({
path: '/normal'
});
六、Nginx配合SpringBoot实现HTTPS强转和API网关负载均衡
user nginx;
worker_processes 16;
error_log logs/error.log;
pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
sendfile on;
keepalive_timeout 65;
gzip on;
// 设置反向代理
upstream apiserver {
server 127.0.0.1:8090 weight=1;
server 127.0.0.1:8091 weight=1;
server 127.0.0.1:8092 weight=1;
server 127.0.0.1:8093 weight=1;
}
server {
listen 80;
server_name upload-image;
// 设置HTTPS强转
rewrite ^(.*)$ https://$host$1 permanent;
}
// API接口使用HTTPS
server {
listen 8899 ssl;
server_name upload-image-api;
// 配置HTTPS
ssl_certificate ../ssl/server.crt;
ssl_certificate_key ../ssl/server.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers ALL:!DH:!EXPORT:!RC4:+HIGH:+MEDIUM:-LOW:!aNULL:!eNULL;
ssl_prefer_server_ciphers on;
// 添加支持的HTTPS协议
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
location / {
proxy_pass http://apiserver;
}
}
server {
// 将前端静态分发设置跳转到该接口
listen 443 ssl;
server_name upload-image-ssl;
ssl_certificate ../ssl/server.crt;
ssl_certificate_key ../ssl/server.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers ALL:!DH:!EXPORT:!RC4:+HIGH:+MEDIUM:-LOW:!aNULL:!eNULL;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
location / {
root html;
index index.html index.htm;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
七、Vue组件水平垂直都居中
就是这个问题,我一直都记不住怎么做,但是我一直都能百度到,连Google都不用...
(1) index.html,设置在style标签
html, body {
margin: 0;
padding: 0;
}
(2) 组件样式
.box {
top: 50%;
left: 50%;
position: absolute;
transform: translate(-50%, -50%);
min-width: 450px;
max-width: 550px;
min-height: 500px;
max-height: 550px;
}
八、Vue与PC端摄像头交互
最近自己用Caffe训练了一个人脸识别的神经网络,以后咱也可以人脸登录了~
So,先搞定PC的Web端的摄像头再说...因为电脑拍出来的照片是不太顺眼的,因此进行了镜像翻转,
但是,你就是那么丑...是我的CSS让你变好看了,哈哈哈~
青芒云(Qimo Cloud)控制台
人脸检测登录,点击图片开始检测
九、Vue中组价高度自适应
让这个组件的高度总是等于浏览器窗口高度!
(1)组件绑定CSS样式
:style="sidebarStyle"
(2) JavaScript数据动态绑定
export default {
name: "Admin",
data: function () {
return {
isCollapse: true,
sidebarStyle: {
'height': ''
}
}
},
methods: {
redressHeight: function () {
this.sidebarStyle.height = window.innerHeight + 'px';
}
},
created() {
window.addEventListener('resize', this.redressHeight);
this.redressHeight();
},
destroyed() {
window.removeEventListener('resize', this.redressHeight);
}
}
持续更新中...