最近有朋友给PicList提issue发现了一个比较奇怪的bug,[Bug]: AWS S3上传文件后 获取的url有问题 · Issue #192 · Kuingsmile/PicList · GitHub,简单的来说,就是在桌面版的PicList中,每上传一次,都会在自定义域名后额外增加一个桶名。经过我的测试,发现确实有这个情况,但奇怪的是用命令行上传时又没有问题。
经过排查和定位,怀疑到了这一行代码:
const userConfig: IAwsS3PListUserConfig = ctx.getConfig("picBed.aws-s3-plist")
if (userConfig.urlPrefix) {
userConfig.urlPrefix = userConfig.urlPrefix.replace(/\/?$/, "")
if (userConfig.pathStyleAccess && !userConfig.disableBucketPrefixToURL) {
userConfig.urlPrefix += "/" + userConfig.bucketName
}
}
从代码来看,只有在这里才对自定义域名添加了桶名后缀,但为什么会每上传一次就多一个桶名而不是清空的呢,继续去看ctx对应的PicGo类中getConfig函数的实现:
getConfig<T> (name?: string): T {
if (!name) {
return this._config as unknown as T
} else {
return get(this._config, name)
}
}
结合到JavaScript的对象赋值的机制,可以发现当getConfig
函数获取到的是一个对象的时候,对userConfig
变量进行赋值后,实际上userConfig
变量保存的是对PicGo实例的this._config.name
对象的同一个引用。因此,直接通过userConfig.urlPrefix += "/" + userConfig.bucketName
修改urlPrefix
属性,就会反映到实例的this._config
对象里的对应属性中。
但还有问题,为什么直接用命令行上传就没有问题,只有使用桌面版才有问题呢?经过梳理,发现是由于在上传时,桌面版每次都传递了相同的PicGo实例,因此上一次对this._config
的修改会影响到下一次的上传,而命令行上传时,每次都会新new一个PicGo实例出来,就不会互相影响。
定位了问题后,修复起来就简单了,将userConfig.urlPrefix
保存的字符串值先赋值给一个新的变量再操作,就不会影响到PicGo实例了。
Comments NOTHING