提示:koa + vue + axios
前言
无法使用koa-session,不知道具体是哪出现了错误,困扰了很久,因此记录一下
一、端口:8080访问:3000遇到跨域问题
问题1:
这里需要设置Allow-Origin为具体的端口地址,虽然设置成*也可以使用,但是控制台会一直报跨域问题
ctx.set("Access-Control-Allow-Origin", "http://localhost:8080");
ctx.set('Access-Control-Allow-Origin', ctx.request.header.origin);
1、不用koa-cors的写法
app.use(async (ctx, next) => {
ctx.set("Access-Control-Allow-Origin", "http://localhost:8080");
ctx.set("Access-Control-Allow-Methods", "OPTIONS, GET, PUT, POST, DELETE");
ctx.set("Access-Control-Allow-Headers", "x-requested-with, accept, origin, content-type");
ctx.set('Access-Control-Allow-Credentials', true);
await next();
})
app.use(router.allowedMethods());
2、koa-cors的写法
app.use(cors({
origin: 'http://localhost:8080',
allowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowHeaders: ['Content-Type', 'Authorization', 'Accept'],
credentials: true
}));
问题2:
直接设置cookie,application空空如也,还会出现跨域问题,这样就需要在后端设置cookie加上domain
ctx.cookies.set('userName', '用户12345');
二、使用步骤
前端vue
1.mian.js
代码如下(示例):
import Vue from 'vue'
import App from './App'
import router from './router'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import store from '@/store/index';
Vue.config.productionTip = false;
Vue.use(ElementUI);
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})
2.router/index.js
代码如下(示例):
import Vue from 'vue'
import Router from 'vue-router'
import Login from '@/components/Login'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'Login',
component: Login
}
]
})
3.api/request.js
代码如下(示例):
import axios from 'axios';
import urlData from '@/utils/urlData'
const request = axios.create({
baseURL: urlData.baseUrl,
});
request.interceptors.request.use(
config => {
return config;
}, err => {
return Promise.reject(err);
});
request.interceptors.response.use((data) => {
return data.data
}, (err) => {
return err
});
const objToQuery = (obj) => {
let urlQuery = '';
for (let key in obj) {
urlQuery += `&${key}=${obj[key]}`
}
return '?'+urlQuery.slice(1);
}
const resquestApi = {
createSvgCode(params) {
return request.get('/api/login/createSvgCode'+objToQuery(params),{
withCredentials: true
});
},
checkSvgCode(params) {
return request.post('/api/login/checkSvgCode',params);
},
}
export default resquestApi;
4.components/Login.vue
代码如下(示例):
<template>
<div class="hello">
<div v-html="svgImg" @click="createSvgCode"></div>
<el-input v-model="svgCode" placeholder=""></el-input>
<el-button type="primary" @click="checkSvgCode"></el-button>
</div>
</template>
<script>
import resquestApi from "@/api/request";
export default {
name: "Login",
data() {
return {
msg: "Welcome to Your Vue.js App",
svgCode: "",
svgImg: "",
userCode:'code_'+Math.floor(Math.random()*10000) +'_'+ new Date().getTime()
};
},
created() {
this.createSvgCode();
},
methods: {
createSvgCode(params) {
resquestApi.createSvgCode({userCode:this.userCode,...params}).then((res) => {
this.svgImg = res.data;
});
},
checkSvgCode() {
resquestApi.checkSvgCode({ code: this.svgCode ,userCode:this.userCode}).then((res) => {
console.log(res, "-------check");
});
},
},
};
</script>
后端koa
npm i koa koa-bodyparser koa-static koa-router koa-cors svg-captcha -S
5.test.js
代码如下(示例):
const Koa = require('koa');
const bodyParser = require('koa-bodyparser');
const staticServe = require('koa-static');
const router = require('koa-router')();
const session = require('koa-session');
const cors = require('koa-cors');
const svgCaptcha = require('svg-captcha');
const app = new Koa();
app.use(cors({
origin: 'http://localhost:8080',
allowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowHeaders: ['Content-Type', 'Authorization', 'Accept'],
credentials: true
}));
app.keys = ["long long ago"];
const session_config = {
key: 'koa:sess',
maxAge: 1000 * 60 * 1,
overwrite: true,
httpOnly: true,
signed: true,
rolling: false,
renew: false
};
app.use(session(session_config, app));
const createSvgCode = (ctx) => {
let captcha = svgCaptcha.create({
size: 4,
fontSize: 50,
width: 120,
height: 36,
background: '#013410'
});
ctx.session[ctx.query.userCode] = {
svgCode: captcha.text,
createTime: new Date().getTime(),
}
ctx.body = {
success: true,
msg: '生成验证码成功',
data: captcha.data
};
}
const checkSvgCode = (ctx) => {
let cookie = ctx.session[ctx.request.body.userCode];
if (!cookie) {
ctx.body = {
success: false,
msg: '验证码无效,请重试!'
}
return
}
if (new Date().getTime() - cookie.createTime > 60000) {
ctx.body = {
success: false,
msg: '验证码过期,请重试!'
}
return
}
if (cookie.svgCode.toLowerCase() != ctx.request.body.code.toLowerCase()) {
ctx.body = {
success: false,
msg: '验证码错误,请重试!'
}
return
}
ctx.body = {
success: true,
msg: '验证码验证成功!'
}
}
router.get(`/api/login/createSvgCode`, createSvgCode);
router.post(`/api/login/checkSvgCode`, checkSvgCode);
app.use(bodyParser());
app.use(staticServe(__dirname + '/public'));
app.use(router.routes());
app.use(router.allowedMethods());
app.listen(3000, () => {
console.log('localhost:3000');
});
效果展示
总结
踩坑路漫漫长@~@
|