vue+django實現下載檔案的示例
阿新 • • 發佈:2021-03-23
一、概述
在專案中,點選下載按鈕,就可以下載檔案。
傳統的下載連結一般是get方式,這種連結是公開的,可以任意下載。
在實際專案,某些下載連結,是私密的。必須使用post方式,傳遞正確的引數,才能下載。
二、django專案
本環境使用django 3.1.5,新建專案download_demo
安裝模組
pip3 install djangorestfhttp://www.cppcns.comramework 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.clic 程式設計客棧kjacking.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檔案
裡面放一個excel檔案,比如:大江大河.xlsx
三、vue專案
新建一個vue專案,安裝ElementUI 模組即可。
新建test.vue
<template> <div style="width: 70%;margin-left: 30px;margin-top: 30px;"> <el-button class="filter-item" type="success" icon="el-icon-download" @click="downFile()">下載</el-button> </div> </template> <script> import axios from 'axios' export default { data() { return { } },程式設計客棧mounted: function() { },methods: { downloadFile(url,options = {}){ return new Promise((resolve,reject) => { // console.log(`${url} 請求資料,引數=>`,JSON.stringify(options)) // axios.defaults.headers['content-type'] = 'application/json;charset=UTF-8' axios({ method: 'post',url: url,// 請求地址 data: options,// 引數 responseType: 'blob' // 表明返回伺服器返回的資料型別 }).then( response => { // console.log("下載響應",response) resolve(response.data) let blob = new Blob([response.data],{ type: 'application/vnd.ms-excel' }) // console.log(blob) // let fileName = Date.parse(new Date()) + '.xlsx' // 切割出檔名 let fileNameEncode = response.headers['content-disposition'].split("filename=")[1]; // 解碼 let fileName = decodeURI程式設計客棧Component(fileNameEncode) // console.log("fileName",fileName) if (window.navigator.msSaveOrOpenBlob) { // console.log(2) navigator.msSaveBlob(blob,fileName) } else { // console.log(3) var link = document.createElement('a') link.h程式設計客棧ref = window.URL.createObjectURL(blob) link.download = fileName link.click() //釋放記憶體 window.URL.revokeObjectURL(link.href) } },err => { reject(err) } ) }) },// 下載檔案 downFile(){ let postUrl= "http://127.0.0.1:8000/download/excel/" let params = { filename: "大江大河.xlsx",} // console.log("下載引數",params) this.downloadFile(postUrl,params) },} } </script> <style> </style>
注意:這裡使用post請求,並將filename傳輸給api,用來下載指定的檔案。
訪問測試頁面,點選下載按鈕
就會自動下載
開啟工具欄,檢視響應資訊
這裡,就是django返回的檔名,瀏覽器下載儲存的檔名,也是這個。
遇到中文,會進行URLcode編碼。
所以在vue程式碼中,對Content-Disposition做了切割,得到了檔名。
以上就是vue+django實現下載檔案的示例的詳細內容,更多關於vue+django實現下載檔案的資料請關注我們其它相關文章!