[Vue2] Vant2 carga archivos usando el método formData, imagen base64 a Blob y luego a Carga de archivos


prefacio

portal de componentes de carga vant2
使用vant2组件中的uploader组件

<van-uploader v-model="fileList" multiple capture :after-read="afterRead" @delete="onDelete" />

提示:以下是本篇文章正文内容,下面案例可供参考

1. El método de convertir base64 a objeto Blob

En la carpeta utils, cree una herramienta js llamadabase64toFile.js

// 转换为 Blob 对象的方法 (可复用)
export function base64ToBlob(base64Data) {
    
    
    const parts = base64Data.split(";base64,");
    const contentType = parts[0].split(":")[1];
    const raw = window.atob(parts[1]);
    const rawLength = raw.length;
    const uInt8Array = new Uint8Array(rawLength);
    for (let i = 0; i < rawLength; ++i) {
    
    
        uInt8Array[i] = raw.charCodeAt(i);
    }
    return new Blob([uInt8Array], {
    
     type: contentType });
}
// 从 base64 数据中获取文件名和 mime 类型的方法 (可复用)
export function getFilenameAndMimetypeFromBase64(base64Data) {
    
    
    const fileInfo = base64Data.split(';base64,')[0].substring(5).split(':');
    const mimeType = fileInfo[0];
    const filename = fileInfo[1];
    return [filename, mimeType];
}
/**
 *  用法
// 将 base64 编码的文件数据转为 Blob 对象
const blob = base64ToBlob(res);
// 获取文件名和 mime 类型
const [filename, mimeType] = getFilenameAndMimetypeFromBase64(res);
// 将 Blob 对象转换为 File 对象
const file = new File([blob], filename, { type: mimeType });
// 上传文件
const formData = new FormData();
formData.append('file', file);

axios.post('/api/upload', formData, {
  headers: {
    'Content-Type': 'multipart/form-data'
  }
}).then(response => {
  console.log(response.data);
}).catch(error => {
  console.log(error);
});
 */

El uso está en el código anterior, que es el siguiente proceso

2. Usar pasos

1. Introducir la herramienta js

El código es el siguiente (ejemplo):

import {
    
    
    base64ToBlob,
    getFilenameAndMimetypeFromBase64
} from "@/utils/base64toFile.js"

2. Escriba el método de carga de formData

Escriba su carga en una carpeta en src /api
inserte la descripción de la imagen aquí

El código es el siguiente (ejemplo):

import request from '@/utils/request'
// 上传图片
export function uploadImg(data) {
    
    
    return request({
    
    
        url: '/flow/common/upload',
        method: 'post',
        headers: {
    
    
            'Content-Type': 'multipart/form-data'
        },
        data: data
    })
}

Modifique la dirección URL de acuerdo con la situación real,

3. El código de solicitud en el método api

Crea uno nuevo en la carpeta utilsrequest.js

import axios from 'axios'
import errorCode from '@/utils/errorCode'
import {
    
    
	getToken
} from '@/utils/auth'
import {
    
    
	Dialog,
	Notify
} from 'vant';
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'

// 创建axios实例
const service = axios.create({
    
    
	// axios中请求配置有baseURL选项,表示请求URL公共部分
	// baseURL: '/',
	baseURL: process.env.VUE_APP_BASE_API,
	// 超时
	timeout: 40000
})
// request拦截器
service.interceptors.request.use(config => {
    
    
	// 是否需要设置 token
	const isToken = (config.headers || {
    
    }).isToken === false
	// config.headers['Authorization'] = sessionStorage.getItem('token') // 让每个请求携带自定义token 请根据实际情况自行修改
	// config.headers['token'] = sessionStorage.getItem('token') // 让每个请求携带自定义token 请根据实际情况自行修改
	config.headers['Authorization'] = 'Bearer ' + getToken()
	// get请求映射params参数
	if (config.method === 'get' && config.params) {
    
    
		let url = config.url + '?';
		for (const propName of Object.keys(config.params)) {
    
    
			const value = config.params[propName];
			var part = encodeURIComponent(propName) + "=";
			if (value !== null && typeof (value) !== "undefined") {
    
    
				if (typeof value === 'object') {
    
    
					for (const key of Object.keys(value)) {
    
    
						let params = propName + '[' + key + ']';
						var subPart = encodeURIComponent(params) + "=";
						url += subPart + encodeURIComponent(value[key]) + "&";
					}
				} else {
    
    
					url += part + encodeURIComponent(value) + "&";
				}
			}
		}
		url = url.slice(0, -1);
		config.params = {
    
    };
		config.url = url;
	}
	return config
}, error => {
    
    
	console.log(error)
	Promise.reject(error)
})
// 响应拦截器
service.interceptors.response.use(res => {
    
    
	// 未设置状态码则默认成功状态
	const code = res.data.code || 200;
	// 获取错误信息
	const msg = errorCode[code] || res.data.msg || errorCode['default']
	// 二进制数据则直接返回
	if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
    
    
		return res.data
	}
	if (code === 401) {
    
    
		return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
	} else if (code === 402) {
    
    
		Dialog.alert({
    
    
			message: res.data.msg,
			confirmButtonColor: "#3478F3",
		}).then(() => {
    
    

		});
		return Promise.reject(new Error(msg))
	} else if (code === 403) {
    
    
		return Promise.reject(new Error(msg))
	} else if (code === 500) {
    
    
		Notify({
    
    
			type: 'danger',
			message: msg
		});
		return Promise.reject(new Error(msg))
	} else if (code === 601) {
    
    
		Notify({
    
    
			type: 'warning',
			message: msg
		});
		return Promise.reject('error')
	} else if (code !== 200) {
    
    
		Dialog({
    
    
			title: '错误',
			message: msg
		});
		return Promise.reject('error')
	} else {
    
    
		return res.data
	}
},
	error => {
    
    
		console.log('err' + error)
		let {
    
    
			message
		} = error;
		if (message == "Network Error") {
    
    
			message = "后端接口连接异常";
		} else if (message.includes("timeout")) {
    
    
			message = "系统接口请求超时";
		} else if (message.includes("Request failed with status code")) {
    
    
			message = "系统接口" + message.substr(message.length - 3) + "异常";
		}
		Notify({
    
    
			message: message,
			type: 'danger',
			duration: 5 * 1000,
		});
		return Promise.reject(error)
	}
)
export default service

request.js tiene muchas clases de herramientas introducidas, pero los proyectos generales de vue deben tener scaffolding, si no lo tiene, o si no ha visto este request.js, puede consultar el código fuente del sistema de gestión de fondo de Ruoyi. Aquí hay solo un ejemplo, que indica que la encapsulación en el método de solicitud son estos códigos


3. Operación real

1. Código HTML

<van-uploader v-model="fileList" multiple capture :after-read="afterRead" @delete="onDelete" />

2. código js

método de importación

import {
    
    
    base64ToBlob,
    getFilenameAndMimetypeFromBase64
} from "@/utils/base64.js"
import {
    
    
    uploadImg, // 上传拍照的图片
} from "@/api/upload.js"

variables de datos

fileList: [],

método de métodos

afterRead(res) {
    
    
    // 此时可以自行将文件上传至服务器
    console.log(res, "file");
    // base64格式赋值, data:image/jpeg;base64,/9j.......
    const data = res.content
    // 将 base64 编码的文件数据转为 Blob 对象
    const blob = base64ToBlob(data);
    // 获取文件名和 mime 类型
    const [filename, mimeType] = getFilenameAndMimetypeFromBase64(data);
    // 将 Blob 对象转换为 File 对象
    const file = new File([blob], res.file.name, {
    
     type: mimeType });
    // 写入formData
    const formData = new FormData();
    formData.append('file', file);
    // 执行上传方法
    uploadImg(formData).then(res => {
    
    
        console.log(res, "上传结果", this.fileList);
        this.form.files.push(res.data) // 写入form参数
    })
},

afterRead es la devolución de llamada del módulo de carga de componentes vant
El contenido de su parámetro de devolución de llamada es una imagen base64data:image/jpeg;base64,/9j.......

Es posible que el nombre de archivo de este código no esté disponible.Después de todo, es un archivo de imagen base64, por lo que el nombre de archivo puede definirlo usted mismo.
inserte la descripción de la imagen aquí

// 获取文件名和 mime 类型
const [filename, mimeType] = getFilenameAndMimetypeFromBase64(res);
// 将 Blob 对象转换为 File 对象
const file = new File([blob], filename, {
    
     type: mimeType });

Resumir

Además de los archivos en formato base64, se pueden cargar mediante formData, y también están disponibles otros documentos como doc y pdf.
只要选择文件上传,拿到的回调参数里面,有一个是file类型的,那就是这个。
toma estoarchivoAgréguelo a formData y luego cárguelo de la misma manera.
como sigue

<el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
    <el-upload class="upload-demo" :file-list="uploadFileList" drag
     :on-change="getFiles" 
    :on-remove="getFiles"
        action="" :auto-upload="false" multiple>
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
        <div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过500kb</div>
    </el-upload>
    <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitFileForm">确 定</el-button>
        <el-button @click="upload.open = false">取 消</el-button>
    </div>
</el-dialog>
// 提交上传文件
submitFileForm() {
    
    
    let formData = new FormData();
    this.files.forEach(f => formData.append("files", f.raw))
    fileUpload(formData).then(res => {
    
    
        this.$modal.msgSuccess("上传成功")
    })
    this.upload.open = false;
},
getFiles(file, fileList) {
    
    
    this.files = fileList;
},

inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/qq_51055690/article/details/131479194
Recomendado
Clasificación