File operations (uni.uploadFile, uni.downloadFile)
File Upload (uni.uploadFile)
uni.uploadFile
is an API in uni-app used to upload local resources to a server. It encapsulates the underlying upload interfaces of platforms like WeChat Mini Programs and H5, providing a unified calling method. The upload process supports operations such as monitoring progress and canceling uploads.
Basic usage:
uni.chooseImage({
success: (res) => {
const tempFilePaths = res.tempFilePaths
uni.uploadFile({
url: 'https://example.com/upload',
filePath: tempFilePaths[0],
name: 'file',
formData: {
'user': 'test'
},
success: (uploadRes) => {
console.log(uploadRes.data);
}
});
}
});
Key parameter descriptions:
url
: Developer server addressfilePath
: Path of the file resource to uploadname
: Key corresponding to the fileformData
: Additional form data in the HTTP request
Common scenarios in actual development:
- Multi-file upload implementation:
const uploadTasks = []
files.forEach((file, index) => {
const task = uni.uploadFile({
url: 'https://example.com/upload',
filePath: file.path,
name: 'file_' + index,
success: () => {
console.log(`File ${index} uploaded successfully`)
}
})
uploadTasks.push(task)
})
// Cancel all uploads
function cancelAll() {
uploadTasks.forEach(task => task.abort())
}
- Upload with progress display:
uni.uploadFile({
url: 'https://example.com/upload',
filePath: tempFilePaths[0],
name: 'file',
success: () => {
uni.showToast({ title: 'Upload successful' })
},
fail: () => {
uni.showToast({ title: 'Upload failed', icon: 'error' })
},
complete: () => {
console.log('Upload completed')
},
progress: (res) => {
console.log('Upload progress', res.progress)
this.progress = res.progress
}
})
File Download (uni.downloadFile)
uni.downloadFile
is used to download file resources from the network to the local device, returning the temporary path of the file. On platforms like WeChat Mini Programs, downloaded files are saved to a temporary directory and require the saveFile
API to be permanently saved.
Basic example:
uni.downloadFile({
url: 'https://example.com/image.jpg',
success: (res) => {
if (res.statusCode === 200) {
console.log('Temporary file path:', res.tempFilePath)
}
}
})
The complete process in practical applications typically includes:
- Downloading the file
- Saving it locally
- Handling the save result
Complete example:
uni.downloadFile({
url: 'https://example.com/report.pdf',
success: (downloadRes) => {
if (downloadRes.statusCode === 200) {
uni.saveFile({
tempFilePath: downloadRes.tempFilePath,
success: (saveRes) => {
const savedFilePath = saveRes.savedFilePath
uni.showModal({
content: 'File saved to: ' + savedFilePath,
showCancel: false
})
}
})
}
},
fail: () => {
uni.showToast({ title: 'Download failed', icon: 'none' })
}
})
Common Issues in File Operations
- Large file upload optimization:
// Chunked upload implementation
async function chunkUpload(file, chunkSize = 1024 * 1024) {
const fileSize = file.size
let offset = 0
let chunkIndex = 0
while (offset < fileSize) {
const chunk = file.slice(offset, offset + chunkSize)
const formData = new FormData()
formData.append('file', chunk)
formData.append('chunk_index', chunkIndex)
formData.append('total_chunks', Math.ceil(fileSize / chunkSize))
await uni.uploadFile({
url: 'https://example.com/upload_chunk',
filePath: chunk,
name: 'chunk',
formData: formData
})
offset += chunkSize
chunkIndex++
}
// Notify the server to merge chunks
await uni.request({
url: 'https://example.com/merge_chunks',
data: {
file_name: file.name,
total_chunks: chunkIndex
}
})
}
- File download renaming:
// Generate a unique filename using a timestamp
function downloadWithRename(url) {
const ext = url.split('.').pop()
const timestamp = new Date().getTime()
const fileName = `download_${timestamp}.${ext}`
uni.downloadFile({
url: url,
success: (res) => {
uni.saveFile({
tempFilePath: res.tempFilePath,
success: (saveRes) => {
// On iOS, direct renaming is not possible; the file must be saved first and then moved
uni.getFileSystemManager().saveFile({
tempFilePath: saveRes.savedFilePath,
filePath: `${wx.env.USER_DATA_PATH}/${fileName}`,
success: (finalRes) => {
console.log('Final save path:', finalRes.savedFilePath)
}
})
}
})
}
})
}
- Cross-platform compatibility handling:
// Differentiate handling based on the running platform
function downloadFile(url) {
// #ifdef H5
// Use an <a> tag for direct download on H5
const link = document.createElement('a')
link.href = url
link.download = ''
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
// #endif
// #ifndef H5
// Use uni.downloadFile on other platforms
uni.downloadFile({
url: url,
success: (res) => {
// Handle download result
}
})
// #endif
}
Security and Permissions
- File upload type restrictions:
uni.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: (res) => {
const file = res.tempFiles[0]
// Check file type
const validTypes = ['image/jpeg', 'image/png']
if (!validTypes.includes(file.type)) {
return uni.showToast({ title: 'Only JPEG/PNG formats are supported', icon: 'none' })
}
// Check file size (5MB limit)
if (file.size > 5 * 1024 * 1024) {
return uni.showToast({ title: 'File size cannot exceed 5MB', icon: 'none' })
}
// Upload after validation
uni.uploadFile({
url: 'https://example.com/upload',
filePath: file.path,
name: 'file'
})
}
})
- Downloaded file security checks:
uni.downloadFile({
url: 'https://example.com/file',
success: (res) => {
// Check file type
uni.getFileInfo({
filePath: res.tempFilePath,
success: (infoRes) => {
if (infoRes.digest !== 'expected file hash') {
return uni.showToast({ title: 'File verification failed', icon: 'none' })
}
// Open the file after security verification
uni.openDocument({
filePath: res.tempFilePath,
fileType: 'pdf',
success: () => {
console.log('Document opened successfully')
}
})
}
})
}
})
Performance Optimization Practices
- Concurrent upload control:
// Maximum concurrency control
class UploadQueue {
constructor(maxConcurrent = 3) {
this.maxConcurrent = maxConcurrent
this.queue = []
this.activeCount = 0
}
add(task) {
return new Promise((resolve, reject) => {
this.queue.push({ task, resolve, reject })
this.next()
})
}
next() {
while (this.activeCount < this.maxConcurrent && this.queue.length) {
const { task, resolve, reject } = this.queue.shift()
this.activeCount++
task()
.then(resolve)
.catch(reject)
.finally(() => {
this.activeCount--
this.next()
})
}
}
}
// Usage example
const uploadQueue = new UploadQueue(2)
files.forEach(file => {
uploadQueue.add(() => new Promise((resolve, reject) => {
uni.uploadFile({
url: 'https://example.com/upload',
filePath: file.path,
name: 'file',
success: resolve,
fail: reject
})
}))
})
- Resumable upload implementation:
// Persist upload state
let uploadState = {
fileId: null,
uploadedSize: 0,
totalSize: 0,
chunks: []
}
// Resume upload
function resumeUpload() {
const state = uni.getStorageSync('uploadState') || uploadState
if (!state.fileId) return
uni.uploadFile({
url: 'https://example.com/resume_upload',
filePath: state.filePath,
name: 'file',
formData: {
file_id: state.fileId,
start_byte: state.uploadedSize
},
progress: (res) => {
const uploaded = state.uploadedSize + res.loaded
state.uploadedSize = uploaded
uni.setStorageSync('uploadState', state)
},
success: () => {
uni.removeStorageSync('uploadState')
}
})
}
- Download caching strategy:
// Download method with caching
const fileCache = {}
function cachedDownload(url) {
// Check memory cache
if (fileCache[url]) {
return Promise.resolve(fileCache[url])
}
// Check local storage
return new Promise((resolve, reject) => {
uni.getSavedFileList({
success: (res) => {
const file = res.fileList.find(f => f.filePath.includes(url))
if (file) {
fileCache[url] = file.filePath
return resolve(file.filePath)
}
// Download if no cache exists
uni.downloadFile({
url: url,
success: (downloadRes) => {
uni.saveFile({
tempFilePath: downloadRes.tempFilePath,
success: (saveRes) => {
fileCache[url] = saveRes.savedFilePath
resolve(saveRes.savedFilePath)
}
})
},
fail: reject
})
}
})
})
}
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn