1.Vue项目创建
1.1 Node.js环境
在创建Vue项目 与.vue编译的时候需要使用Node.js环境.
JavaScript是脚本语言, Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境.
拓展一些模块 os 网络通信的模块 文件处理 ...
* 1. 访问 http://nodejs.cn/ 下载node, 一致next到底 ---> 安装成功!
Node历史版本: https://nodejs.org/zh-cn/download/releases/
* 2. 查看是否安装成功, 在命令提示符中输入 node -v, 可以看见node的版本及说明安装成功!
node命令 ==> python
npm命令 ==> pip
C:\Users\13600>node -v
v16.14.2
1.2 Vue脚手架
* 1. 安装模块
命令: npm install 模块名 # npm访问外网安装.
* 2.安装cnpm, 国内使用淘宝的cnpm来替换npm
npm install -g cnpm --registry=https://registry.npm.taobao.org
* 3. 安装vue脚手架
命令: cnpm install -g @vue/cli
* 4. 如果第三步出错, 清除缓存后重新执行第一, 二步程序(最好以管理员方式运行)
npm cache clean --force
* 5. 查看是否安装成功直接输入: vue
2. 创建Vue项目
创建项目 (需要从git上拉取)
方式一: 图形化界面
vue ui 会启动一个服务, 用浏览器访问创建vue项目
方式二: 命令行方式
vue create myfirstvue
2.1 图形化创建项目
* 1 命名行中输入 vue ui 启动图形化界面服务
ctrl + c 停止服务
终止批处理操作吗(Y/N)? y
* 2. 访问vue的创建页面
地址: http://localhost:8000/
* 3. 项目名称, 选择包管理器
* 4. 选择预设
* 5. 选择项目的功能
babel: js的es版本转换, 新语法在浏览器中不指代, 会将高版本的语法转为低版本的语法.
router: 路由跳转.
vuex: 状态管理器, 存放数据,
* 6. 选择vue版本
* 7. 将配置保存为预设中的一个选项. (不保存)
设置保存之后, 下次再创建项目在提供这个预设选项, 使用此次的项目配置,
* 8. 等到下在代码创建项目
* 9. 创建成功
2.2 命令行创建项目
* 1. 命令行创建vue项目
在D盘建立一个vue目录, D:\vue ,
切换到D:\vue下创建
命令: vue create luffy_vue
* 2. 进入vue界面
* 3. 选择项目配置
上下↑↓ 移动, 空格选中或取消, 回车确定!
babel: js的es版本转换, 新语法在浏览器中不指代, 会将高版本的语法转为低版本的语法.
router: 路由跳转.
vuex: 状态管理器, 存放数据,
* 4. 选择Vue版本 2.x
* 5. 保存记录, Y/n 都可以
* 6. 选择json格式文件存放依赖信息
* 7. 将此次的配置保存为一个模块 N
* 8. 从git下载
3. 使用PyCharm打开vue项目
* 1. 安装Vue.js插件
* 2. 使用PyCharm打开创建的vue项目
* 3. 启动项目 npm run serve (需要注意所在的路径 )
每次运行项目, 需要对文件进行编译最后启动项目
* 4. 访问 http://localhost:8080/
默认访问的是主页
* 5. 设置PyCharm的启动按钮启动服务
设置之后便可以通过按钮启动
4. 目录介绍
luffy_vue
|--node_modules 项目依赖库
|--publice/ 项目共有资源
|--favicon.ico 站点图标
|--index.html 主页(在这个页面中切换组件)
|--src/
|--assets/ 前台静态资源总目录
|--img 前台图片资源
|--css/ 自定义css样式存放目录
|--global.css 自定义全局样式
|--settings.py 自定义配置文件
|--js/ 自定义js样式存放目录
|--components/ 小组件目录
|--views/ 页面组件目录
|--App.vue 根组件
|--main.js 入口脚本文件
|--router/ 路由存放目录
|--index.js 路由脚本文件
|--store 仓库
|--index.js 仓库脚本文件
|--vue.config.js 项目配置文件
|--package.json 项目依赖库的详细信息
删除不必要的小组件与页面组件
删除 src/components/HelloWorld.vue 小组件
删除 views的HomeView.vue的 中HelloWord相关的代码
删除 src/views/AboutView.vue 页面组件
删除 router/index.js 中about的路由配置
删除 src/App.vue 中about的导航条配置
5. 跨域请求
5.1 同源策略
同源策略是浏览器的安全策略, 如果浏览器对javascript没有同源策略的保护, 那么一些重要的机密网站将会很危险.
同源策略: 不允许不同域之间直接通信直接通信.
请求的url地址, 必须与浏览器上的url地址处于同域上, 也就是域名, 端口, 协议相同.
比如:我在本地上的域名是127.0.0.1:8000, 请求另外一个域名: 127.0.0.1:8001
浏览器上就会报错,.
5.2 跨站请求测试
写两个django项目进行测试.
* 1. 项目1(端口号为8008)
from django.contrib import admin
from django.urls import path, re_path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
re_path(r'^get_data/', views.get_data)
]
from django.http import JsonResponse
def get_data(request):
print(f'{request.method} 请求访问 get_data')
return JsonResponse({'k1': 'v1'})
修改端口号为8008
启动项目, 浏览器访问 http://127.0.0.1:8008/get_data/
* 2. 项目2 (端口号为8000)
from django.contrib import admin
from django.urls import path, re_path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
re_path(r'^index/', views.index)
]
from django.shortcuts import render
def index(request):
return render(request, 'index.html')
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>客户端</title>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
</head>
<body>
<button onclick="click1">发送请求</button>
</body>
<script>
function click1() {
$.ajax({
url: 'http://127.0.0.1:8008/get_data/',
type: 'get',
success: function (args) {
console.log(args)
}
})
}
</script>
</html>
1. 先启动server项目, 在启动client项目,
2. 浏览器访问 https://127.0.0.1:8000/index/
3. 点击按钮向https://127.0.0.1:8008/get_data/
4. 报错已拦截跨源请求, 同源策略禁止读取... 原因:CORS 头缺少 'Access-Control-Allow-Origin'
5. 可以看到服务端是收到了请求, 并返回了数据, 最后被浏览器拦截了
5.3 CORS简单/非简单请求
ps:
xss: 跨站脚本攻击
csrf: 跨站请求伪造
cors: 跨域资源共享
只要同时满足以下两大条件,就属于简单请求, 凡是不同时满足下面两个条件, 就属于非简单请求.
1. 请求方法是以下三种方法之一:
HEAD
GET
POST
2. HTTP的头信息是以下几种字段:
Accept: 发送端(客户端)希望接受的数据类型.
Accept-Language: 希望采用的语言或语言组合.
Content-Language: 用来表示报文体(实体数据)使用的语言(ch,fr,en,ja等).
Last-Event-ID: 标识最后一次接受的event id.
Content-Type: 发送端(客户端|服务器)发送的实体数据的数据类型.
默认只限于三个值application/x-www-form-urlencoded, multipart/form-data, text/plain
浏览器对这两种请求的处理, 是不一样的.
简单请求:只会发送一次请求, 为返回数据对象时, 在响应头中添加,
Access-Control-Allow-Origin(访问控制允许源)的信息则可以资源共享.
非简单请求: 会发送两次请求, 第一次发送OPTIONS请求用于做预检,
预检请求时, 允许请求方式则需服务器设置响应头: Access-Control-Request-Method
预检请求时, 允许请求头则需服务器设置响应头:Access-Control-Request-Headers (允许额外的头或数据类型)
才会再以次发送请求用于数据传输。
1. 简单请求资源共享
跨域资源共享, 本质就是在响应头部加入允许, 允许某些域, 允许某些头, 添加的域和头就能正常访问.
简单请求需要允许访问的域,
非简单请需要先设置允许某些头. 再设置域.
在项目1的视图函数中, 返回数据对象的时候在响应头中添加Access-Control-Allow-Origin的信息.
HttpResponse[key] = value 在响应头中添加数据
Access-Control-Allow-Origin为键, 允许跨站获取资源的地址为值.
from django.shortcuts import render
from django.http import JsonResponse
def get_data(request):
print(f'{request.method} 请求访问 get_data')
response = JsonResponse({'k1': 'v1'})
response['Access-Control-Allow-Origin'] = 'http://127.0.0.1:8000'
return response
使用使用rest_farmework的Response返回数据,
则为Response的headers响应头参数设置{'Access-Control-Allow-Origin': '*'}
2. 非简单请求资源共享
* 1. 修改项目2模板文件, 提交json格式的数据到后端
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>客户端</title>
<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
</head>
<body>
<button onclick="click1()">发送json数据</button>
</body>
<script>
function click1() {
$.ajax({
url: 'http://127.0.0.1:8008/get_data/',
type: 'post',
contentType: 'application/json',
data: JSON.stringify({'k1': 'v1'}),
success: function (args) {
console.log(args)
}
})
}
</script>
</html>
* 2. 将项目1的csrf检验关闭
MIDDLEWARE = [
...
...
* 3. 先启动项目1, 在启动项2, 浏览器访问 127.0.0.1:8000/indiex/
访问控制标头不允许请求标头字段内容类型
* 4. 修改项目1的视图函数,
如果是OPTIONS请求则在响应头中设置Access-Control-Allow-Headers(访问控制允许标头)
def get_data(request):
print(f'{request.method} 请求访问 get_data',)
response = JsonResponse({'k1': 'v1'})
if request.method == 'OPTIONS':
response['Access-Control-Allow-Headers'] = 'Content-Type'
response['Access-Control-Allow-Origin'] = 'http://127.0.0.1:8000'
return response
* 5. 先启动项目1, 在启动项2, 浏览器访问 127.0.0.1:8000/indiex/
先发送了OPTIONS, 预检通过再一次发送请求进行通信.
3. 中间件中实现资源共享
* 1. 将跨域资源共享的代码写入到自定义中间件的请求响应方法中. 那么所有的视图类视图方法都可以实现资源共享.
在项目1的 项目目录下新建utils文件夹, 在改文件夹中新建CorsMiddleware Cors中间件
from django.utils.deprecation import MiddlewareMixin
class CorsMiddleware(MiddlewareMixin):
def process_response(self, request, response):
if request.method == 'OPTIONS':
response['Access-Control-Allow-Headers'] = 'Content-Type'
response['Access-Control-Allow-Origin'] = 'http://127.0.0.1:8000'
return response
* 3. 将自定义中间件添加到配置文件中
MIDDLEWARE = [
'utils.CorsMiddleware.CorsMiddleware',
...
* 3. 将视图函数中的Cors配置删除
def get_data(request):
print(f'{request.method} 请求访问 get_data',)
response = JsonResponse({'k1': 'v1'})
return response
* 4. 先启动项目1, 在启动项2, 浏览器访问 127.0.0.1:8000/indiex/
总结: 在中间件中允许域, 允许头.
4. django-cors-header模块
使用django-cors-header模块解决跨域问题.
* 1. 安装模块(默认安装最新的版本 需要django3.2版本及以上)
pip install django-cors-headers==2
* 2. django-cors-header是一个app, 需要注册在app列表中才能使用
INSTALLED_APPS = [
...
'corsheaders',
]
* 3. 添加中间件
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
...
* 4. 在配置文件setting.py中配置django-cors-header使用的参数
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
CORS_ORIGIN_WHITELIST = ('地址1', '地址1')
CORS_ALLOW_METHODS = (
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
'VIEW',
)
CORS_ALLOW_HEADERS = (
'XMLHttpRequest',
'X_FILENAME',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
'Pragma',
)
不需要全部配置选一些常用的请求方法和标头即可.
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_METHODS = (
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
)
CORS_ALLOW_HEADERS = (
'authorization',
'content-type',
)
6. 前后端交互
6.1 后端配置
全后端分别是一个项目使用的地址和端口都不一样, 会出现同源策略问题.
在luffy项目(后端)使用django-cors-header模块实现Cors资源共享.(依据5.3.4小节设置)
6.2 前端配置
在luffy_vue项目(前端)中使用axios发送ajax信息给后端交互.
* 1. 安装axios (-S将安装的模块信息添加到package.json文件中)
npm install axions -S
* 2. 为了方便以后的调用, 在vue的配置文件main.js 中导入 axios模块, 将模块存在Vue对象的属性中.
import axios from 'axios'
Vue.prototype.$axios = axios
* 3. 在src/views/HomeView.vue页面组件中使用created生命周期钩子函数中使用axios发送ajax请求.
访问全局异常&日志接口http://127.0.0.1:8000/user/exception_log/
访问之后有两种情况:
1. 连接成功返回一个对象, 执行.then()方法,
对象被.then()方法中函数的参数接收, 参数.data拿到返回的数据.
2. 连接失败, 得到一个AxiosError对象, 执行.catch()方法,
AxiosError对象被.catch()方法中函数的参数接收.
<script>
export default {
name: 'HomeView',
created(){
this.$axios.get('http://127.0.0.1:8000/user/exception_log/').then(args=>{
console.log(args.data)
}).catch(error=>{
console.log(error)
})
}
}
</script>
* 4. 启动luffy(后端)项目, 在启动luffy_vue前端项目
访问luffy的页面, 页面中会使用homeview页面组件, 它又会去触发created生命周期钩子函数,
最后得到返回的数据, 表示连接成功.
|