axios数据发送与后台响应

本文详细介绍了axios在vue项目中的数据发送,包括post请求的四种编码方式、文件传输和日期格式化处理。通过实例解析了如何正确设置数据传输格式,确保数据能正确到达后台。

axios数据发送与后台响应

在写vue项目时,肯定会用到的就是axios。我们可以通过axios将数据从后台读取然后也可以进行数据的修改等操作。但对于没有经验的人来说,第一次使用axios的post时会出现很多意想不到的事情。下面我们通过几个简单的示例来探究以下到底如何玩转axios的数据发送。

1. 前期准备

首先,要能发送数据,那就必须先创建一个vue。下面是一个简单的例子。

<template>
    <div>
        <button @click="sendTo">111</button>
    </div>
</template>

<script>
    export default {
        name: 'Test',
        methods: {
            sendTo () {
                this.axios({
                    url: '/hello/',
                    method: 'post'
                }).then(res => {
                    console.log('111')
                }).catch(error => {
                    console.log('222')
                })
            }
        }
    }
</script>

注意:在axios内部是并没放置任何数据的,后面我们会仔细的讲解一下。

接下来就是配置router

const TestVue = () => import('@/views/Test')

{
    path: '/test',
    component: TestVue
},

最后就是在后台写一个hello视图函数

def hello(request):
    print(111)
    return JsonResponse({"hello": 'hello'})

到现在为止,我们的前期工作也就完成了。

2. 实验开始

首先,我们看看这样的一个是否能调试成功

在这里插入图片描述

当我们按下111这个按钮之后,看下会发生什么。

在这里插入图片描述

可以看到,因为点击111按钮之后,我们的页面会自动跳转到后台。由于此时我们并没有发送任何数据,因此POST和body是没有任何数据的。这样的情况同样可以在开发者工具中发现。

在这里插入图片描述

这里并没有出现body部分。而出现两个hello/是因为第一个请求是OPTION的,查看该视图是否支持POST方法(具体的在跨域问题中已经讲过)。接下来,我们在axios中添加数据查看会发生什么。

2.1 直接在axios的data中添加相关的数据

this.axios({
    url: '/hello/',
    method: 'post',
    data: {
        'hello': 'hello',
        'world': 'world'
    }
})

同样的,我们还是打开页面,看看会出现什么。

在这里插入图片描述

很奇怪,我们并没有在POST属性中看到任何数据而是只在body中存在二进制的数据。我们在回到开发者工具中看看会是什么。

在这里插入图片描述

可这里明明是已经发送数据的。这是为什么呢?

2.2 post提交的四种编码方式

application/x-www-form-urlencoded

这应该是最常见的post编码方式,一般的表单提交默认以此方式提交。大部分服务器语言对这种方式都有很好的支持。而我们在项目中都基本上使用这种方式进行提交和获取。

multipart/form-data

这也是一种比较常见的post数据格式,我们用表单上传文件时,必须使form表单的enctype属性或者ajax的contentType参数等于multipart/form-data。使用这种编码格式时发送到后台的数据长得像这样子 .

不同字段以–boundary开始,接着是内容描述信息,最后是字段具体内容。如果传输的是文件,还要包含文件名和文件类型信息(后面会讲这个)

application/json

axios默认提交就是使用这种格式。如果使用这种编码方式,那么传递到后台的将是序列化后的json字符串。因此如果在django后台获取到我们输入的键值对,那就必须通过``json.loads`进行获取。

text/xml

因此,当我们了解到正常情况下,post使用json方式往后台传参数,那我们就可以直接使用json.loads函数将其解开,然后在使用。

在这里插入图片描述

没错,这样的确是一个很好的办法,但别忘了,POST是一个非常危险的方法,接触到POST方法的必定是需要对数据库进行操作的,因此这样的情况下如果直接使用body里面的内容很容易被居心叵测的人利用。因此,我们还是希望使用request.POST.get()进行获取对象,这样可行么?

2.3 使用application/x-www-form-urlencoded传输数据

答案是肯定的,当我们在传输数据的时候,我们可以将post的编码方式转化为application/x-www-form-urlencoded,这样就可以直接在后台获取到该键值对。例子如下。

this.axios({
    url: '/hello/',
    method: 'post',
    data: {
        'hello': 'hello',
        'world': 'world'
    },
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
})

可我们打开后台,发现POST虽然能拿到数据,但不是我们的键值对:

在这里插入图片描述

你可能会想到,会不会是因为data的键使用的是字符串,让他以为我们整个是字符串,我们要是直接变成一个变量呢?

this.axios({
    url: '/hello/',
    method: 'post',
    data: {
        hello: 'hello',
        world: 'world'
    },
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
})

结果还是一样,出现的是一整个作为键。

在这里插入图片描述

其实这个地方,我们需要使用一个parms来将我们需要传到后台的键值对进行收集,然后再发送。

let parms = new URLSearchParams()
parms.append('hello', 'hello')
parms.append('world', 'world')
this.axios({
    url: '/hello/',
    method: 'post',
    data: parms,
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
})

接下来,我们看看会发生什么

在这里插入图片描述

牛逼的事情出来了,我们再POST中已经形成了相应的键值对,而开发者工具中也进行了相应的变化。

在这里插入图片描述

所以,如果想前台传参进入后台,并不是直接在data中放置数据,你还必须设置post提交的编码方式和一个存放所有键值对的容器。

3. 文件传输

文件也是日常使用必不可少的东西,比如我们的更换头像、更换背景图片等。那这些东西也能通过刚才的编码方式进行传输么?答案是否定的。接下来我们继续探秘一下。

同样的,先写一个input,然后再data中存放一个file用来接收数据

<template>
    <div>
        <input type="file" v-model="file">
        <button @click="sendTo">111</button>
    </div>
</template>

<script>
    export default {
        name: 'Test',
        data () {
            return {
                file: ''
            }
        },
        methods: {
            sendTo () {
                let parms = new URLSearchParams()
                parms.append('hello', 'hello')
                parms.append('world', 'world')
                parms.append('file', this.file)
                this.axios({
                    url: '/hello/',
                    method: 'post',
                    data: parms,
                    headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
                }).then(res => {
                    console.log('111')
                }).catch(error => {
                    console.log('222')
                })
            }
        }
    }
</script>

当你写完这个,好家伙打开网页发现,一顿爆红,主要原因如下:

在这里插入图片描述

这是因为还是按照原本的思路使用v-model是不行的,需要@change

<input type="file" @change="file">

所以我们改完之后再次发起请求,看看会出现什么:

在这里插入图片描述

很奇怪,file里面并没有我们想要的数据,其实这是因为你不能直接使用file去获取该对象,而是应该使用一个函数去一次获取files内部的值然后添加进去。

<template>
    <div>
        <input type="file" @change="FileGet($event)">
        <button @click="sendTo">111</button>
    </div>
</template>

<script>
    export default {
        name: 'Test',
        data () {
            return {
                file: ''
            }
        },
        methods: {
            sendTo () {
                let parms = new URLSearchParams()
                parms.append('hello', 'hello')
                parms.append('world', 'world')
                parms.append('file', this.file)
                this.axios({
                    url: '/hello/',
                    method: 'post',
                    data: parms,
                    headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
                }).then(res => {
                    console.log('111')
                }).catch(error => {
                    console.log('222')
                })
            },
            FileGet (event) {
                let files = event.target.files
                for (let i = 0; i < files.length; i++) {
                    this.file = files[i]
                }
                console.log(this.file)
            }
        }
    }
</script>

此时,当我们配置好之后,将文件放入,然后再console就会出现file的相关信息。

在这里插入图片描述

嗯,非常不错。基本上的东西都完成了,那我们提交试试。当按下按钮之后,发现file里面是一个file对象

在这里插入图片描述

其实在外层还有一个FILES对象,文件将被存放在这里。但我们发现这里面并没用任何的数据。

在这里插入图片描述

还记得post提交的四种方式么?我们的文件并不适合application/x-www-form-urlencoded而因该使用multipart/form-data进行传输。因此我们还是需要再次进行修改。并且需要将容器修改成FormData

sendFile () {
    let formData = new FormData()
    formData.append('hello','hello')
    formData.append('world','world')
    formData.append('file',this.file)
    this.axios({
        url: '/hello/',
        method: 'post',
        data: formData,
        headers: { 'Content-Type': 'multipart/form-data' }
    }).then(res => {
        console.log(111)
    }).catch(error => {
        console.log(222)
    })
}

配置完成以后,我们就可以来玩file了。

在这里插入图片描述

简单的方法

  • 获取文件名:request.FILES.get('file', '').name.split('.')

在这里插入图片描述

  • 保存文件
def hello(request):
    file_obj = request.FILES.get('file', '')
    if file_obj:
        # 更改名字,将原来的名字改为summer.原来的后缀名
        file_name = "summer." + '.'.join(file_obj.name.split('.')[1:])
        with open(os.path.join('./static/file', file_name), 'wb') as w:
            for block in file_obj.chunks():
                w.write(block)

    return JsonResponse({"hello": 'hello'})

4. 日期小bug

在写日期的时候,我们前端使用日期选择器获取到的日期是一个中英文参杂的字符串,因此这样传入到后台是无法处理的。因此我们需要用到monent

<div>
	<input type="file" @change="FileGet($event)">
	<bk-date-picker v-model="initDateTime" :placeholder="'选择日期时间'" :type="'datetime'"></bk-date-picker>
	<button @click="sendDate">111</button>
</div>

<script>
	sendDate () {
        console.log(this.initDateTime)
    }
</script>

当我们写好这个之后,页面上的确出现的是我们想要的格式。

在这里插入图片描述

但我们获取initDateTime数据查看却发现该数据不是这样的

在这里插入图片描述

因此,为了获得我们想要的日期格式,我们就需要使用monent

import moment from 'moment'

sendDate () {
    console.log(this.initDateTime)
    let time = moment(this.initDateTime).format("YYYY-MM-DD hh:mm:ss")
    console.log(time)
}

在这里插入图片描述

至此也就全部完成了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值