在进行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 字节):

有三种格式

  1. <bucket>,表示允许用户上传文件到指定的 bucket。在这种格式下文件只能新增(分片上传需要指定insertOnly为1才是新增,否则也为覆盖上传),若已存在同名资源(且文件内容/etag不一致),上传会失败;若已存在资源的内容/etag一致,则上传会返回成功。
  2. <bucket>:<key>,表示只允许用户上传指定 key 的文件。在这种格式下文件默认允许修改,若已存在同名资源则会被覆盖。如果只希望上传指定 key 的文件,并且不允许修改,那么可以将下面的 insertOnly 属性值设为 1。
  3. <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 来判断文件内容是否一致

  • 两个名词解释
  • 覆盖上传,无论前面有没有,都读取的最新的一次结果
  • 新增,是只成功第一次,后面的全部失败

正在加载ing
12 声望3 粉丝