vue前后台交互
- 前后端使用相同的协议
- 接口协议
axios
配置axios来完成前后台ajax请求
安装 axios(ajax)的命令
cnpm install axios
// 为项目配置全局axios,配置环境
import Axios from 'axios'
//Vue.prototype.$ajax = Axios;//命名方式1
Vue.prototype.$axios = Axios;//命名方式2,vue框架常使用
export default {
name: "Cars",
components: {
Car
},
data() {
return {
cars_data: []
}
},
created() {
// 组件一加载,就从后台请求数据
// 1、jq完成ajax请求,一般不使用
/*
$.ajax({
url: this.$settings.base_url + '/cars/',
type: 'get',
success(response) {
console.log(response)
}
});
*/
}
}
使用
export default {
name: "Cars",
components: {
Car
},
data() {
return {
cars_data: []
}
},
created() {
// 2、vue有专门用来完成ajax请求的插件:axios
this.$ajax({
url: this.$settings.base_url + '/cars/',
method: 'get',
params: {
// url拼接的数据
},
data: {
// 请求携带的数据报数据
}
}).then((response) => {//成功
console.log(response);
this.cars_data = response.data;
}).catch(error => {//失败
console.log(error)
})
let _this = this
this.$ajax({
method: 'post',
url: 'http://127.0.0.1:5000/loginAction',
params: {
usr: this.usr,
ps: this.ps
}
}).then(function(res) {
// this代表的是回调then这个方法的调用者(axios插件),也就是发生了this的重指向
// 要更新页面的title变量,title属于vue实例
// res为回调的对象,该对象的data属性就是后台返回的数据
_this.title = res.data
}).catch(function(err) {
window.console.log(err)
})
# 用pycharm启动该文件模拟后台
from flask import Flask, request, render_template
from flask_cors import CORS
app = Flask(__name__)
CORS(app, supports_credentials=True)
@app.route('/')
def index():
return "<h1>主页</h1>"
@app.route('/loginAction', methods=['GET', 'POST'])
def test_action():
# print(request.args)
# print(request.form)
# print(request.values)
usr = request.args['usr']
ps = request.args['ps']
if usr != 'abc' or ps != '123':
return 'login failed'
return 'login success'
if __name__ == '__main__':
app.run()
django后台处理跨域(cors)问题
安装插件
在diango环境下安装
>: pip install django-cors-headers
插件参考地址:https://github.com/ottoyiu/django-cors-headers/
项目配置:settings.py
# 注册app
INSTALLED_APPS = [
...
'corsheaders'
]
# 添加中间件
MIDDLEWARE = [
...
'corsheaders.middleware.CorsMiddleware'
]
# 允许跨域源
CORS_ORIGIN_ALLOW_ALL = True
配置完成后可以进行交互
后端返回数据的时候需要注意
一般返回JsonResponse数据类型
from django.http import JsonResponse
注意:JsonResponse返回的是字典类型,如果是其他的可迭代类型,选择用下面的形式返回
cars_data = [
{
'name': '玛莎拉蒂',
'price': 12.5
},
{
'name': '劳斯莱斯',
'price': 32
}
]
return JsonResponse(data=cars_data, safe=False, json_dumps_params={'ensure_ascii': False})
中间件问题
前后端分离后csrf这个中间件便不会被使用,所以需要进行注释
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'corsheaders.middleware.CorsMiddleware',
]
登陆的前后端分离
django后端
def login(request, *args, **kwargs):
if request.method == 'GET':
print(request.GET)
print(request.POST)
print(request.body)
elif request.method == 'POST':
print(request.GET)
print(request.POST)
print(request.body)
# usr必须是Bob,pwd必须是123
import json
dic = json.loads(request.body)
usr = dic.get('usr')
pwd = dic.get('pwd')
if usr == 'Bob' and pwd == '123':
return JsonResponse({
'msg': '登录成功',
'result': 'bob.123.xyz',
})
return JsonResponse({
'msg': '登录失败',
'result': ''
})
vue前端
<template>
<div class="login">
<el-row>
<el-col :span="12" :offset="6">
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="账号">
<el-input type="text" v-model="form.usr"></el-input>
</el-form-item>
<el-form-item label="密码">
<el-input type="password" v-model="form.pwd"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">登录</el-button>
</el-form-item>
</el-form>
</el-col>
</el-row>
</div>
</template>
<script>
export default {
name: "Login",
data() {
return {
form: {
usr: '',
pwd: ''
}
}
},
methods: {
onSubmit() {
if (!this.form) {
return;
}
this.$ajax({
url: this.$settings.base_url + '/login/',
method: 'post',
params: { // url拼接参数
p1: '123'
},
// data: { // 数据包参数
// d1: 'xyz'
// }
data: this.form
}).then(response => {
this.$message({
message: response.data.msg,
type: 'warning'
});
// 有响应的登录认证码,存储在cookie中
// 设置:set(key, val, exp)
// 取值:get(key)
// 删除:remove(key)
let token = response.data.result;
if (token) {
// this.$cookies.set('token', token, '2d');
// this.$cookies.set('token', token, 2 * 24 * 3600 * 365);
// console.log(this.$cookies.get('token'));
// this.$cookies.remove('token');
}
})
}
}
}
</script>
<style scoped>
.el-form {
height: 296px;
border: 2px solid darkcyan;
border-radius: 10px;
margin: calc(50vh - 200px) 0;
padding: 30px;
}
</style>