Open FrankKai opened 5 years ago
<input>
,DataTransfer, 或者HTMLCanvasElement.mozGetAsFile()
new File(bits, name[, options])
此处的bits是一个数组,数组元素可以由ArrayBuffer,ArrayBufferView,Blob或者DOMString组成;fileName指明文件名称或者文件路径;options里的type属性指明MIME类型,lastModified属性指明上次修改时间,默认是Date.now();multipart/form-data
也需要用FormData组装数据 其实就是http的request header指定了 {Content-Type: 'multipart/form-data'}
可以参考我的另一个记录:blob Url那些事儿
tips:
const formData = new FormData(); // 由于服务端编码格式为multipart/form-data,所以需要构造一个FormData对象
const file = new File([blobObj], fileName, { type: blobObj.type }); // 传入blob对象创建一个File实例
formData.append('file', file);// formData实例增加file对象
const options = {
method: 'post',
url: 'https://foo.bar.com/baz',
headers: { 'Content-Type': 'multipart/form-data' }, // 上传相关
data: formData, // 上传相关
};
axios.request(options).then(()=>{}).catch(()=>{});
ali-oss是一个Node环境和Browser环境皆可用的对象存储服务package。
import OSS from 'ali-oss';
const token = apiNode.generateOssToken({ type }) // 调用nodejs端接口,根据类型生成某个bucket有效的token
this.client = new OSS(token);
const blobObj = new Blob([u8arr], { type: mime });
this.client
.put(fileName, blobObj) // 这里我们传入的值blob对象,ali-oss仅支持浏览器端的Blob对象
.then((data) => {
if (data && data.name) {
return data.name; // OSS返回的文件名
}
})
.catch(() => {});
可以再伪代码基础上用document.cookie设置token的有效时长;上传重试等等护航功能。
关键是ali-oss SDK的put方法,它主要用来向bucket添加一个object。
.put(name, file[,options])
- name String类型的文件名
- {String|Buffer|ReadStream|File(only support Browser)|Blob(only support Browser)} object local path, content buffer or ReadStream content instance use in Node, Blob and html5 File
qiniu-js是一个基于七牛API开发的前端SDK。
import * as qiniu from 'qiniu-js';
const putExtra = { fname: '', params: {}, mimeType: null };// fname文件原文件名,params自定义变量,mimeType数组,限制文件上传类型
const config = {
useCdnDomain: true, // 表示是否使用 cdn 加速域名
disableStatisticsReport: false, // 是否禁用日志报告,为布尔值,默认为 false
retryCount: 5, // 上传自动重试次数(整体重试次数,而不是某个分片的重试次数);默认 3 次(即上传失败后最多重试两次);目前仅在上传过程中产生 599 内部错误时生效,但是未来很可能会扩展为支持更多的情况
region: qiniu.region.z0, // 选择上传域名区域;当为 null 或 undefined 时,自动分析上传域名区域
};
const token = apiNode.generateOssToken({ type }) // 调用nodejs端接口,根据类型生成某个bucket有效的token
this.observable = qiniu.upload(obj.file, obj.fileName, token, putExtra, config);
this.observable.subscribe({
next: (res) => {
this.emit('progress', Math.ceil(res.total.percent));
},
error: (err) => {
this.clear();
this.emit('error', err, obj.imgName);
},
complete: (res) => {
this.clear();
this.emit('complete', res.hash, obj.imgName);
},
});
关键是qiniu-js SDK的upload方法,它是上传的核心。
qiniu.upload(file: blob, key: string, token: string, putExtra: object, config: object): observable file: Blob 对象,上传的文件 key: 文件资源名 token: 上传验证信息,前端通过接口请求后端获得 config: 包括cdn加速,日志报告,上传区域名,上传自动重试次数,分片上传的请求并发数,MD5校验等等 putExtra: 自定义的一些内容
其次就是这个上传成功后的返回的observable对象,在其中可以做一些上传后的处理。
这个方法本身是一个observable对象,有subscribe方法,主要有next和error,complete三个事件。
next: 接收上传进度信息,res是一个带有 total 字段的 object,包含loaded、total、percent三个属性,提供上传进度信息。 error:上传错误后触发;自动重试本身并不会触发该错误,而当重试次数到达上限后则可以触发。当不是 xhr 请求错误时,会把当前错误产生原因直接抛出,诸如 JSON 解析异常等;当产生 xhr 请求错误时,参数 err 为一个包含 code、message、isRequestError 三个属性的 object complete: 接收上传完成后的后端返回信息,具体返回结构取决于后端sdk的配置
与自家服务端和ali-oss不同的是,qiniu-js提供了除成功和失败额外的next事件,可以实时监测到上传的进度,用户感知上传进度是起码的用户体验。
图片,音频,视频等等这几种常见的资源类型,如果需要从前端上传到服务端,有几种方式呢?不妨回顾一下经历过的项目想一想。
项目上也用到很多上传文件的地方,七牛云,阿里云OSS,讯飞web api上传都接触过,所以在这里做一个记录,总结一下前端上传的几种方式。