最近在做一个项目,需要在前端对图片切片并上传到七牛云
技术要点
- canvas.toBlob(blob=>{}); //可将canvas保存成二进制文件
- formData.append('file', blob, 'filename'); //将二进制文件添加到FormData中
- ajax.send(formData); //上传数据到后端处理
代码实现
目前没有看到七牛云提供的JSSDK支持上传blob到云上的, 所以这里自己实现了一下
注意ajax post formData到七牛云的时候不要设置content-type,让浏览器自己处理class Qiniu { constructor(options = {}) { this._options = {...options}; } ajax(url = '', opt = {}) { const options = {method: 'GET', async: true, dataType: 'JSON', ...opt}; return new Promise((resolve, reject) => { const ajax = this.createAjax(); if (ajax) { const _async = typeof options.async === 'boolean' ? options.async : true; ajax.open(options.method || 'GET', url, _async); if (options.headers) { Object.keys(options.headers).forEach(key => { ajax.setRequestHeader(key, options.headers[key]); }); } ajax.onreadystatechange = () => { if (ajax.readyState === 4) { if (ajax.status >= 200 && ajax.status <= 400) { let res = ajax.responseText; if (options.dataType && options.dataType.toUpperCase() === 'JSON') { res = JSON.parse(res); } resolve(res, ajax.response); } else { reject(new Error('请求失败:' + ajax.status)) } } }; ajax.send(options.data); } else { reject(new Error('创建Ajax请求失败!')); } }); } createAjax() { let xmlhttp; if (window.XMLHttpRequest) { xmlhttp = new XMLHttpRequest(); } else { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } return xmlhttp; } getToken() { if (this._options.token) { return Promise.resolve(this._options.token); } else { if (typeof this._options.getToken === 'function') { const t = this._options.getToken(); if (t && typeof t.then === 'function') { return t.then(token => { this._options.token = token; return token; }) } else if (typeof t === 'string') { this._options.token = t; return Promise.resolve(t); } else { return Promise.reject(new Error('options.getToken必须返回Promise或string token')); } } else if (typeof this._options.getTokenUrl === 'string') { return this.ajax(this._options.getTokenUrl, { headers: { authorization: this._options.authorization } }).then(res => { this._options.token = res.uptoken; return this._options.token; }).catch(ex => { throw new Error('获取uptoken失败:' + ex.message); }); } else { return Promise.reject(new Error('无法获取token')); } } } upload(file, filename, key) { return this.getToken().then(token => { const formData = new FormData(); formData.append('key', key || filename); formData.append('token', token); formData.append('file', file, filename); return formData; }).then(data => { //注意不要设置content-type,浏览器自动会填充 return this.ajax('http://upload.qiniu.com/', { method: 'POST', data, }); }); }}canvas.toBlob(blob => { const filename = Date.now() + Math.random() + '.png'; const qiniu = new Qiniu({getTokenUrl:'这里写获取七牛token的接口地址'}); qiniu.upload(blob, filename);}, 'image/png');