1.学城项目 Vue项目创建&Cors资源共享&前后端通信

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/

GIF 2022-4-5 14-46-42

* 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

image-20220430204347425

* 3. 安装vue脚手架
     命令: cnpm install -g @vue/cli
* 4. 如果第三步出错, 清除缓存后重新执行第一, 二步程序(最好以管理员方式运行)
     npm cache clean --force

2022-04-30_00444

* 5. 查看是否安装成功直接输入: vue

image-20220430210509364

2. 创建Vue项目

创建项目 (需要从git上拉取)
	方式一: 图形化界面
  	        vue ui   会启动一个服务, 用浏览器访问创建vue项目
	方式二: 命令行方式
		   vue create myfirstvue

2.1 图形化创建项目

* 1 命名行中输入 vue ui 启动图形化界面服务

image-20220509155016162

ctrl + c 停止服务
终止批处理操作吗(Y/N)? y
* 2. 访问vue的创建页面
     地址: http://localhost:8000/

2022-05-09_00564

* 3. 项目名称, 选择包管理器

2022-05-09_00566

* 4. 选择预设

2022-05-09_00567

* 5. 选择项目的功能
     babel: js的es版本转换, 新语法在浏览器中不指代, 会将高版本的语法转为低版本的语法.
     router: 路由跳转.
     vuex: 状态管理器, 存放数据,

2022-05-09_00568

* 6. 选择vue版本

2022-05-09_00569

* 7. 将配置保存为预设中的一个选项. (不保存)
     设置保存之后, 下次再创建项目在提供这个预设选项, 使用此次的项目配置,

image-20220509160526111

* 8. 等到下在代码创建项目

image-20220509160537924

* 9. 创建成功

image-20220509160748194

2.2 命令行创建项目

* 1. 命令行创建vue项目   
     在D盘建立一个vue目录, D:\vue , 
	 切换到D:\vue下创建
	 命令: vue create luffy_vue

image-20220512200902582

* 2. 进入vue界面

2022-04-30_00450

* 3.  选择项目配置
      上下↑↓ 移动, 空格选中或取消, 回车确定!

2022-04-30_00451

babel: js的es版本转换, 新语法在浏览器中不指代, 会将高版本的语法转为低版本的语法.
router: 路由跳转.
vuex: 状态管理器, 存放数据,
* 4. 选择Vue版本 2.x

image-20220509153355846

* 5. 保存记录, Y/n 都可以

image-20220430212629079

* 6. 选择json格式文件存放依赖信息

image-20220430212723476

* 7.  将此次的配置保存为一个模块 N

image-20220430212914329

* 8. 从git下载

image-20220430213205947

3. 使用PyCharm打开vue项目

* 1. 安装Vue.js插件

image-20220430215754488

* 2. 使用PyCharm打开创建的vue项目
* 3. 启动项目 npm run serve  (需要注意所在的路径  )
     每次运行项目, 需要对文件进行编译最后启动项目

image-20220430220230923

* 4. 访问 http://localhost:8080/
     默认访问的是主页

image-20220430220454831

* 5. 设置PyCharm的启动按钮启动服务

2022-05-12_00618

设置之后便可以通过按钮启动

image-20220430220718066

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相关的代码

2022-04-30_00465

删除 src/views/AboutView.vue 页面组件
删除 router/index.js 中about的路由配置
删除 src/App.vue 中about的导航条配置

2022-05-12_00619

image-20220512203440266

5. 跨域请求

5.1 同源策略

同源策略是浏览器的安全策略, 如果浏览器对javascript没有同源策略的保护, 那么一些重要的机密网站将会很危险.

同源策略: 不允许不同域之间直接通信直接通信.
请求的url地址, 必须与浏览器上的url地址处于同域上, 也就是域名, 端口, 协议相同.

比如:我在本地上的域名是127.0.0.1:8000, 请求另外一个域名: 127.0.0.1:8001
浏览器上就会报错,.

5.2 跨站请求测试

写两个django项目进行测试.
* 1. 项目1(端口号为8008)

image-20220512211741549

# 路由层
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

# Create your views here.

def get_data(request):
    print(f'{
      
      request.method} 请求访问 get_data')
    return JsonResponse({
    
    'k1': 'v1'})
修改端口号为8008

image-20220512212715801

启动项目, 浏览器访问 http://127.0.0.1:8008/get_data/

image-20220512212748918

* 2. 项目2 (端口号为8000)

image-20220512210610229

# 路由层
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


# Create your views here.
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. 可以看到服务端是收到了请求, 并返回了数据, 最后被浏览器拦截了	

image-20220512233532889

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


# Create your views here.

def get_data(request):
    print(f'{
      
      request.method} 请求访问 get_data')
    response = JsonResponse({
    
    'k1': 'v1'})

    # * 代表允许所有求访问
    # response['Access-Control-Allow-Origin'] = '*'
    # 单独配置
    response['Access-Control-Allow-Origin'] = 'http://127.0.0.1:8000'

    return response

image-20220512222006391

使用使用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 = [
	...
    # 'django.middleware.csrf.CsrfViewMiddleware',
    ...
* 3. 先启动项目1, 在启动项2, 浏览器访问 127.0.0.1:8000/indiex/
     访问控制标头不允许请求标头字段内容类型

image-20220512233848031

* 4. 修改项目1的视图函数, 
     如果是OPTIONS请求则在响应头中设置Access-Control-Allow-Headers(访问控制允许标头)
def get_data(request):
    print(f'{
      
      request.method} 请求访问 get_data',)
    response = JsonResponse({
    
    'k1': 'v1'})

    # 如果是非简单请求发送的是OPTIONS请求, 在响应中添加 访问控制允许标头的信息
    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, 预检通过再一次发送请求进行通信.

image-20220512235404210

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':
            # 允许头的之后 Content-Type的不在限制
            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/

image-20220513001038199

总结: 在中间件中允许域, 允许头.
4. django-cors-header模块
使用django-cors-header模块解决跨域问题.
* 1. 安装模块(默认安装最新的版本 需要django3.2版本及以上)
     pip install django-cors-headers==2

image-20220513235749567

* 2. django-cors-header是一个app, 需要注册在app列表中才能使用
INSTALLED_APPS = [
    ...
    'corsheaders',
]
* 3. 添加中间件
MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    # 注册自己的中间件
    # 'utils.CorsMiddleware.CorsMiddleware',
    ...
* 4. 在配置文件setting.py中配置django-cors-header使用的参数
# CORS_允许_凭据
CORS_ALLOW_CREDENTIALS = True
# CORS起源允许所有
CORS_ORIGIN_ALLOW_ALL = True
# CORS起源白名单 需要https:// 开头
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_允许_凭据
CORS_ALLOW_CREDENTIALS = True
# CORS起源允许所有
CORS_ORIGIN_ALLOW_ALL = True
# 允许的方法
CORS_ALLOW_METHODS = (
	'DELETE',
	'GET',
	'OPTIONS',
	'PATCH',
	'POST',
	'PUT',
)
# 允许的标头
CORS_ALLOW_HEADERS = (
	'authorization',
	'content-type',
)

image-20220513003247136

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

2022-05-13_00641

* 2. 为了方便以后的调用, 在vue的配置文件main.js 中导入 axios模块, 将模块存在Vue对象的属性中.
// 导入axios模块
import axios from 'axios'
// 通过Vue的原型将值存放在Vue中, 以后Vue对象通过.属性取到axios, Vue的属性一般都在属性名前加上$标识
Vue.prototype.$axios = axios

image-20220513093103243

* 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=>{
      
        // eg: 如果连接不上失败得到AxiosError对象或服务器中报错
      console.log(error)
    })
  }
}
</script>

image-20220513093342746

* 4. 启动luffy(后端)项目, 在启动luffy_vue前端项目
     访问luffy的页面, 页面中会使用homeview页面组件, 它又会去触发created生命周期钩子函数,
     最后得到返回的数据, 表示连接成功.

image-20220513093204217

猜你喜欢

转载自blog.csdn.net/qq_46137324/article/details/124743476