在进行apk功能上传的时候,发现了一个问题,关于上传到七牛的文件到底是能不能被覆盖,以下是查阅文档和七牛同学的结论
同名文件是否被覆盖
在server端生成token的时候 我们是这样写的
const policyParams = { scope: bucket }
const putPolicy = new qiniu.rs.PutPolicy(policyParams)
const uploadToken = putPolicy.uploadToken(mac)
return uploadToken
可以看到 设置 policyParams 对象 是生成token的第一步
policyParams 的其实还有很多其余key, 可以查看 七牛文档
而其中涉及到关于文件是否进行覆盖操作的两个key是 scope 和 insertOnly
七牛中关于 scope 参数的解释
指定上传的目标资源空间 Bucket 和资源键 Key(最大为 750 字节):
有三种格式
- <bucket>,表示允许用户上传文件到指定的 bucket。在这种格式下文件只能新增(分片上传需要指定insertOnly为1才是新增,否则也为覆盖上传),若已存在同名资源(且文件内容/etag不一致),上传会失败;若已存在资源的内容/etag一致,则上传会返回成功。
- <bucket>:<key>,表示只允许用户上传指定 key 的文件。在这种格式下文件默认允许修改,若已存在同名资源则会被覆盖。如果只希望上传指定 key 的文件,并且不允许修改,那么可以将下面的 insertOnly 属性值设为 1。
- <bucket>:<keyPrefix>,表示只允许用户上传指定以 keyPrefix 为前缀的文件,当且仅当 isPrefixalScope 字段为 1 时生效,isPrefixalScope 为 1 时无法覆盖上传。
而我们项目里是采用的第一种,按照第一种的逻辑:
若已存在同名资源但是内容不一致,上传会失败;若已存在同名字资源的内容一致,则上传会返回成功
本地测试的时候发现,如果是两个同名但是内容不同图片上传,则第二次会失败
然后使用 两个同名但是内容不同的APK包进行测试,则发现第二次上传提示成功了
为什么都是进行同名文件但是内容不同,七牛上传的结果却不一样呢
第一条规则中,有这样一句话: 分片上传需要指定insertOnly为1才是新增,否则也为覆盖上传
根据结果推测, 在进行APK上传的时候,应该是使用的分片上传,所以采用了覆盖模式
但是项目中并没有配置相关参数是否使用分片上传
咨询了七牛的同学,回复说,七牛文件上传以4M做为分界点,大于4M 默认分片上传 小于4M 默认表单上传
测试中 APK 已经在4M 之上了,所以默认使用了 分片上传,同时 policyParams 参数中并没有设置 insertOnly ,导致了这里使用了覆盖上传的策略 ,所以第二次同名APK可以上传成功
为何同名文件发生覆盖后,点击链接查看的还是原来的文件
在大文件第二次上传覆盖后,使用原本的链接将文件下载下来,会发现文件内容并没有更新。
但是的确是第二次上传成功了
七牛同学回复,要更新CDN缓存 , 也就是即使文件更新成功,但是如果不主动通过接口去更新CDN的缓存,那么用户通过链接看到的文件内容也是旧版的文件
补充:
- 查看七牛进行文件内容是否一致判断
七牛判断文件内容是否一致,https://github.com/qiniu/qetag/blob/master/qetag.js 通过这个函数可以生成一个 etag 字符串
`
getEtag('./xxx_6.10.2_a1_test.apk', etags => {
console.log('origin1', etags)
})
getEtag('./same/xxx_6.10.2_a1_test.apk', etags => {
console.log('same111', etags)
})
getEtag('./copy/xxxx_6.10.2_a1_test.apk', etags => {
console.log('origin2', etags)
})`
七牛通过对比生成的 etag 来判断文件内容是否一致
- 两个名词解释
- 覆盖上传,无论前面有没有,都读取的最新的一次结果
- 新增,是只成功第一次,后面的全部失败
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。