vue+django实现下载文件的示例

一、概述

在项目中,点击下载按钮,就可以下载文件。

传统的下载链接一般是get方式,这种链接是公开的,可以任意下载。

在实际项目,某些下载链接,是私密的。必须使用post方式,传递正确的参数,才能下载。

二、django项目

本环境使用django 3.1.5,新建项目download_demo

vue+django实现下载文件的示例_第1张图片

安装模块

pip3 install djangorestframework django-cors-headers

修改文件download_demo/settings.py

INSTALLED_APPS = [
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'api.apps.ApiConfig',
 'corsheaders', # 注册应用cors
]

注册中间件

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', # 注册组件cors
]

最后一行增加

# 跨域增加忽略
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True

CORS_ALLOW_METHODS = (
 'GET',
 'OPTIONS',
 'PATCH',
 'POST',
 'VIEW',
)

CORS_ALLOW_HEADERS = (
 'XMLHttpRequest',
 'X_FILENAME',
 'accept-encoding',
 'authorization',
 'content-type',
 'dnt',
 'origin',
 'user-agent',
 'x-csrftoken',
 'x-requested-with',
 'Pragma',
)

修改download_demo/urls.py

from django.contrib import admin
from django.urls import path
from api import views

urlpatterns = [
 path('admin/', admin.site.urls),
 path('download/excel/', views.ExcelFileDownload.as_view()),
]

修改api/views.py

from django.shortcuts import render,HttpResponse
from download_demo import settings
from django.utils.encoding import escape_uri_path
from django.http import StreamingHttpResponse
from django.http import JsonResponse
from rest_framework.views import APIView
from rest_framework import status
import os

class ExcelFileDownload(APIView):
 def post(self,request):
  print(request.data)
  # filename = "大江大河.xlsx"
  filename = request.data.get("filename")
  download_file_path = os.path.join(settings.BASE_DIR, "upload",filename)
  print("download_file_path",download_file_path)

  response = self.big_file_download(download_file_path, filename)
  if response:
   return response

  return JsonResponse({'status': 'HttpResponse', 'msg': 'Excel下载失败'})

 def file_iterator(self,file_path, chunk_size=512):
  """
  文件生成器,防止文件过大,导致内存溢出
  :param file_path: 文件绝对路径
  :param chunk_size: 块大小
  :return: 生成器
  """
  with open(file_path, mode='rb') as f:
   while True:
    c = f.read(chunk_size)
    if c:
     yield c
    else:
     break

 def big_file_download(self,download_file_path, filename):
  try:
   response = StreamingHttpResponse(self.file_iterator(download_file_path))
   # 增加headers
   response['Content-Type'] = 'application/octet-stream'
   response['Access-Control-Expose-Headers'] = "Content-Disposition, Content-Type"
   response['Content-Disposition'] = "attachment; filename={}".format(escape_uri_path(filename))
   return response
  except Exception:
   return JsonResponse({'status': status.HTTP_400_BAD_REQUEST, 'msg': 'Excel下载失败'},
        status=status.HTTP_400_BAD_REQUEST)

在项目根目录创建upload文件

vue+django实现下载文件的示例_第2张图片

 里面放一个excel文件,比如:大江大河.xlsx

三、vue项目

新建一个vue项目,安装ElementUI 模块即可。

新建test.vue





注意:这里使用post请求,并将filename传输给api,用来下载指定的文件。 

访问测试页面,点击下载按钮

就会自动下载

vue+django实现下载文件的示例_第3张图片

打开工具栏,查看响应信息

vue+django实现下载文件的示例_第4张图片

这里,就是django返回的文件名,浏览器下载保存的文件名,也是这个。

遇到中文,会进行URLcode编码。

所以在vue代码中,对Content-Disposition做了切割,得到了文件名。

以上就是vue+django实现下载文件的示例的详细内容,更多关于vue+django实现下载文件的资料请关注脚本之家其它相关文章!

你可能感兴趣的:(vue+django实现下载文件的示例)