vue2前端和django后端上传文件和下载文件(分别是mp4和gif)

本文详细介绍了如何使用Vue通过FormData和$.ajax实现MP4文件上传到Django后端,并处理跨域问题。同时,展示了Django如何返回gif文件供Vue下载,包括axios的使用和FileResponse在Django中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.vue给django传MP4(FornData)

(用FormData装提交的文件, $.ajax发送, 代理服务器跨域)

1-1.vue($.ajax + 代理服务器)

上传input组件要加type="button,这样点击后就不会刷新页面(好像默认submit会刷新页面)

<form class="form-horizontal" id="uploadForm" method="post" action="" enctype="multipart/form-data">
	<input type="file" id="file3"  name="file" multiple='' accept=".mp4"/>
	<input type="button" value="上传" id="submit" @click="check()">
</form>

script中,使用ajax传FormData,这里面的$是因为用了jquery

function check() {
	//mp4   3gp    mov
	var doc = document.getElementById('file');
	for(var i=0;i<doc.files.length;i++){
		var name = doc.files[i].name;
		var hz = name.substring(name.lastIndexOf(".")+1);
		if(hz!="mp4" && hz!="3gp" && hz!="mov" && hz!="MP4" && hz!="3GP" && hz!="MOV"){
			$.messager.alert("错误信息","请上传mp4、3gp、mov视频格式!!",'error');
			return false;
		}
	}
	upload();	
}
 
function upload(){
	 var formData = new FormData($('#uploadForm')[0]);
     $.ajax({
          type: 'post',
          // url: "<%=path%>/shipin/ftpupload.do",
          url: "/api/api/fileUpload/upload/",
          data: formData,
          cache: false,       //是否在缓存中读取数据的读取
          processData: false, //用于对data参数进行序列化处理
          contentType: false, //发送信息至服务器时内容编码类型,上传文件时设置为false
     }).then(function (data) {
      console.log(data)
      console.log(data.msg)
    	 if(data.msg=='Success'){
    		 alert("上传成功!");
    	 }else if(data==1){
    		 $.messager.alert("错误信息","上传失败!",'error',function(){});
    	 }else{ 		
    		 $.messager.alert("错误信息","请选择需要上传的文件!",'error',function(){});   		
    	 }    	
     });
}			

关于跨域问题,参考:
Vue之Axios跨域问题解决方案

1-2.django

在view.py中添加如下代码,返回HttpResponse传递是否成功写入的信息

import json
import os
import re
import time
import uuid
from pathlib import Path

from django.middleware.csrf import get_token
from django.views.decorators.http import require_http_methods

@require_http_methods(["GET", "POST"])
@csrf_exempt
def returnfile(request):
    print('here returnfile')
    # print("request",request)
    # print("request.FILES:",request.FILES.get('file'))
    # return HttpResponse("这个HTTP显示还是挺有意思的!")

    response = {}
    try:
        if request.method == 'GET':
            get_token(request)
        if request.method == 'POST':
            req = request.FILES.get('file')
            print("req:",req) # None
            print("request.FILES:",request.FILES) # <MultiValueDict: {}>
            print("request:",request) # <WSGIRequest: POST '/api/fileUpload/upload/'>
            print("request.POST:",request.POST) # <QueryDict: {}>
            
            #  上传文件类型过滤
            # file_type = re.match(r'.*\.(txt|doc|docx)', req.name)
            file_type = re.match(r'.*\.(txt|doc|docx|mp4)', req.name)
            print("file_type:",file_type)
            print("req.name",req.name)
            
            if not file_type:
                response['code'] = 2
                response['msg'] = '文件类型不匹配, 请重新上传'
                return HttpResponse(json.dumps(response))

            # 将上传的文件逐行读取保存到list中
            file_info = {'date': '', 'name': '', 'uuid': '', 'path': ''}
            content = []
            for line in req.read().splitlines():
                # print("line:", line)
                content.append(line)
            # print("type:", type(content[0]))
            # print("content[0].decode:", content[0].decode("utf-8"))
            # print("req.read():", req.read())

            # 打开特定的文件进行二进制的写操作
            dir_path_str = "./file"
            print("save_dir:",Path(os.path.abspath(dir_path_str)))
            Path(dir_path_str).mkdir(exist_ok=True)
            
            # file_path = os.path.join(dir_path_str, req.name)
            file_path = os.path.join(dir_path_str, "mv.mp4")
            print("file_path:",file_path)
            destination = open(file_path, 'wb+')
            for chunk in req.chunks():  # 分块写入文件
                destination.write(chunk)
            destination.close()

            # 生成当前文件生成UUID
            file_info['uuid'] = uuid.uuid1()
            # 上传文件的时间
            time_stamp = time.time()
            now = int(round(time_stamp * 1000))
            file_info['date'] = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(now / 1000))
            # 文件名称
            file_info['name'] = req.name


            # 返回状态信息
            # response['check'] = str(content[0].decode('utf-8'))
            response['msg'] = "Success"
            response['code'] = 200

    except Exception as e:
        print(e)
        response['msg'] = '服务器内部错误'
        response['code'] = 1
    # 在前端显示为{msg: 'Success', code: 200}
    return HttpResponse(json.dumps(response), content_type="application/json")

记得添加urls

2.django给vue传gif

(用axios发请求, FileResponse装服务器文件, a标签点击下载)

2-1. 在vue中

1-2-1.第一种方式

参考:找不到了
仅在vue文件的template中添加下载链接,其中href是我的后端下载链接,点击即可下载

<a href="http://127.0.0.1:8000/api/download">下载</a>

1-2-2.第二种方式

参考:找不到了
在vue文件的template中加入

<button @click="download()">下载文件</button>

在script的export const{…,methods:{}}中加入函数

import {downloadFile} from "../api/api";
export default{
  name:'AboutView', // 随便一个view都行
  data(){
    return{
    // ...
    }
  },
  methods:{
    download(){
      downloadFile()
    },
  },
}

在…/api/api.js中(这里我改了href为自己的)

//先定义axios
export const downloadFile = () => {
  return axios({
    method:'get',
    url:'/api/download/',
    responseType: 'blob', // 表明返回服务器返回的数据类型
  }).then(res => {
    console.log('/api/download/的responce',res)
    const content = res
    const blob = new Blob([content])
    const fileName = 'output.gif'
    if ('download' in document.createElement('a')) { // 非IE下载
      console.log("非IE下载")
      const elink = document.createElement('a')
      console.log("elink",elink)
      elink.download = fileName
      elink.style.display = 'none'
      // elink.href = URL.createObjectURL(blob)
      elink.href = 'http://127.0.0.1:8000/api/download'
      console.log("elink.href",elink.href)
      document.body.appendChild(elink)
      elink.click()
      URL.revokeObjectURL(elink.href) // 释放URL 对象
      document.body.removeChild(elink)
    } else { // IE10+下载
      console.log("IE10+下载")
      navigator.msSaveBlob(blob, fileName)
    }
  })
}

2-2. 在django框架的app.view.py中添加视图,注意:

因为django框架运行起来的命令是python manage.py runserver
所以文件读取都以manage.py的路径为路径
例子:
我的django后端项目的文件夹叫back,manage.py在该目录下
使用python manage.py runserver运行后端
若在app/view.py中读取face_output.gif文件
那么读的文件路径为(back)/face_output.gif(与manage.py同目路径,而不与app/view.py同路径)

@csrf_exempt
def download(request):
    response = FileResponse(open(r"face_output.gif", "rb")) # 注意face_output.gif是和manage.py同目录的
    response['Content-Type'] = 'application/octet-stream'
    response['Content-Disposition'] = "attachment;filename=filename.gif"  # 注意filename不支持中文
    return response

记得添加urls
参考:https://blog.youkuaiyun.com/lishuaigell/article/details/124226453

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值