将django服务器中的压缩包, 从浏览器中下载出来。
压缩包的格式不同于普通文件,需要对请求头做额外设置
def download(request):
logger = logging.getLogger('Django')
params = json.loads(request.body)
# 拿到文件在数据库中存储的位置
media_file = params.get("filePath")
# 拼接文件路径
filepath = os.path.join(settings.MEDIA_ROOT, media_file)
# 拿到文件的名字(该名字包含了文件的格式)
filename = media_file.split(r'/')[-1]
file = open(filepath, 'rb')
response = FileResponse(file) # 生成文件对象application/msword application/octet-stream
response['Content-Type'] = 'application/octet-stream'
# name.split('.')[0] + '.docx',
name = filename
response['Content-Disposition'] = 'attachment;filename ="%s"' % (
name.encode('utf-8').decode('ISO-8859-1'))
logger.info("文件下载," + media_file)
return response
res是上一个请求的返回结果。 这里的responseType只是一个标志位,用于与其他正常的post请求区分。
that.$http({
method: "post",
url: "/app01/download/",
responseType: "blob",
params: {
filePath: res.filePath,
},
})
.then(
(response) => {
const filename = res.fileName + ".zip";
const blob = new Blob([response], {
type: "application/zip",
});
if (window.navigator.msSaveOrOpenBlob) {
navigator.msSaveBlob(blob, filename);
} else {
var link = document.createElement("a");
link.href = window.URL.createObjectURL(blob);
link.download = filename;
link.click();
// 释放内存
window.URL.revokeObjectURL(link.href);
}
},
(err) => {
}
);
压缩包需要额外设置请求头, 否则压缩时会提示文件夹损坏。
之前使用的一直是instance,所以提示文件夹损坏, 新增instance2添加请求头和响应体设置。
import axios from 'axios'
import api from './api'
//创建axios实例对象
let instance = axios.create({
baseURL: 'http://127.0.0.1:8000', //服务器地址
timeout: 5000 //默认超时时长
})
let instance2 = axios.create({
baseURL: 'http://127.0.0.1:8000', //服务器地址
timeout: 5000, //默认超时时长
responseType: 'blob',
headers: { 'Content-Type': 'application/json; application/octet-stream' },
})
//请求拦截器
instance.interceptors.request.use(config => {
//此处编写请求拦截的代码,一般用于弹出加载窗口
console.log('正在请求……')
return config
}, err => {
console.error('请求失败', err)
})
//响应拦截器
instance.interceptors.response.use(res => {
//此处对响应数据做处理
console.log('请求成功!')
return res //该返回对象会传到请求方法的响应对象中
}, err => {
// 响应错误处理
console.log('响应失败!', err)
// return Promise.reject(err);
})
//封装axios请求方法,参数为配置对象
//option = {method,url,params} method为请求方法,url为请求接口,params为请求参数
async function http(option = {}) {
let result = null
if (option.method === 'get' || option.method === 'delete') {
//处理get、delete请求
await instance[option.method](
option.url,
{ params: option.params }
).then(res => {
result = res.data
}).catch(err => {
// 这里进行了捕获,方法中不需要再次进行捕获,也捕获不到
result = err
})
} else if (option.method === 'post' || option.method === 'put') {
//处理post、put请求
// 如果有参数, 则使用新的instance
if (option.responseType) {
await instance2[option.method](
option.url,
option.params
).then(res => {
result = res.data
}).catch(err => {
result = err
})
} else {
await instance[option.method](
option.url,
option.params
).then(res => {
result = res.data
}).catch(err => {
result = err
})
}
}
return result
}
export default http
django部分的代码
django文件夹压缩
压缩包解压时报错文件已损坏
vue部分的代码