Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

通过 API 删除图片,接口返回成功,但是实际并没有被删除 #366

Closed
hellodk34 opened this issue Mar 30, 2022 · 22 comments
Closed
Labels
bug Something isn't working

Comments

@hellodk34
Copy link

首先感谢大佬开发兰空图床,非常好用,谢谢。

前几天写了一个 PicGo 插件适配了兰空图床 V1 和 V2 https://github.com/hellodk34/picgo-plugin-lankong

今天在做 PicGo 相册中同步删除功能时,发现调用 API 成功,但是实际上图片并没有被删除。

20220330171809

通过 postman 之类的工具调用删除接口 status 返回了 true,而且多次调用均返回了 true(不应该只允许一次 true 么),源图床站使用了 cdn,但是多次调用 status 依然 true ?

在 web 页面上主动删除一张图片通过 F12 发现调用了 /user/images 接口,公开 API 是 /api/v1/images/:KEY,两个也不一样,想知道我这是哪里出了问题,还是 Lsky Pro V2 删除 API 有 bug?

@wisp-x
Copy link
Collaborator

wisp-x commented Mar 30, 2022

使用的是七牛云储存吗?

@hellodk34
Copy link
Author

尚不清楚使用的什么 cdn,源图床站是 https://dogimg.com/

我拿我自己部署的试试,套的 cf cdn

@wisp-x
Copy link
Collaborator

wisp-x commented Mar 30, 2022

如果是七牛云储存,删除图片目前是有问题的,详细:#331 (comment)
程序删除操作永远都是返回成功的状态,目的是避免修改、删除了储存策略配置导致删除失败的问题。如果发现物理图片没有删除成功,正常情况下在程序 storage/logs 目录里可以找到详细的错误日志。

@hellodk34
Copy link
Author

好的,谢谢指出,晚上回去我再看看日志,刚刚用我自己部署的测试也似乎是没有删掉,晚上回去看一下日志。有问题我再反馈,感谢你飞快的回复。💗️

@hellodk34
Copy link
Author

20220330203033

我在自己的服务器上测试,删除前查到文件在服务器上,成功调用删除接口后文件依然在原位置。

storage/logs/laravel-2022-03-23.log 日志里似乎没有什么有用的信息

[2022-03-23 11:43:24] prod.ERROR: Api 上传文件时发生异常 {"file":"/var/www/html/vendor/intervention/image/src/Intervention/Im     age/AbstractDecoder.php","line":351,"message":"Image source not readable","trace":"#0 /var/www/html/vendor/intervention/image     /src/Intervention/Image/AbstractDriver.php(66): Intervention\\Image\\AbstractDecoder->init(NULL)

...

#32 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Barryvdh\\Debugbar\\Middleware\\InjectDebugbar->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#33 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#34 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(31): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#35 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#36 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#37 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(40): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#38 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\TrimStrings->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#39 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#40 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#41 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(86): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#42 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#43 /var/www/html/vendor/fruitcake/laravel-cors/src/HandleCors.php(52): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#44 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Fruitcake\\Cors\\HandleCors->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#45 /var/www/html/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php(39): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#46 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Http\\Middleware\\TrustProxies->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#47 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#48 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(142): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#49 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(111): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter(Object(Illuminate\\Http\\Request))
#50 /var/www/html/public/index.php(52): Illuminate\\Foundation\\Http\\Kernel->handle(Object(Illuminate\\Http\\Request))
#51 {main}"}

@hellodk34
Copy link
Author

20220330204525

20220330204551

删除时是使用上传成功后返回的 data.key

@wisp-x
Copy link
Collaborator

wisp-x commented Mar 30, 2022

删除时是使用上传成功后返回的 data.key

是的,另外删除物理文件的前提条件是不存在其他相同 md5、sha1 值的文件记录,程序为了节省空间占用,上传相同的图片不会重复创建物理文件,所以系统中可能会出现多条记录指向同一个文件。

@hellodk34
Copy link
Author

好的,谢谢指教。但是我这个问题我不知道该如何排查了……

@wisp-x
Copy link
Collaborator

wisp-x commented Mar 30, 2022

@hellodk34 目前还未遇到本地储存无法删除文件的情况,你可以试一下上传图床里不存在的图片,然后看一下图片的权限,无论是接口删除还是通过 web 删除,删除方式都是一样的没有差异,顺便在看一下该图片的缩略图有没有被删除成功。如果不是上述我所说的多个纪录指向同一个文件的原因,那大概率就是因为权限导致的无法删除了。

所以系统中可能会出现多条记录指向同一个文件

如果有这个情况出现,删除其中某一个文件记录,不会删除物理文件。

@hellodk34
Copy link
Author

hellodk34 commented Mar 30, 2022

@wisp-x 权限是 755,owner 和 group 都是 www-data,刚刚通过 web 删除文件成功,但是其缩略图并没有被删掉。通过接口调用,文件和缩略图都没有被删掉。

ps: 我通过 web 删除了图片并没有触发 我的图片 自动刷新,是 nginx 或 apache 配置问题吗?

@wisp-x
Copy link
Collaborator

wisp-x commented Mar 30, 2022

@hellodk34 看描述很玄学,不清楚什么问题。

@hellodk34
Copy link
Author

@wisp-x 感谢这么晚一直追踪问题。有空你也可以自己尝试一下,可以用这个图床 然后还有我写的适配兰空图床的 PicGo 图片上传插件 🙏🏻

@hellodk34
Copy link
Author

hellodk34 commented Mar 30, 2022

看描述很玄学,不清楚什么问题。

@wisp-x 回头重新部署一个看看,这次部署是根据别人的一个不成熟的 Docker 镜像装的。

@HalcyonAzure
Copy link

HalcyonAzure commented Mar 31, 2022

看描述很玄学,不清楚什么问题。

@wisp-x 回头重新部署一个看看,这次部署是根据别人的一个不成熟的 Docker 镜像装的。

我今天试了下我在issues里面发的Docker容器,通过您的PicGo插件删除确实复现了同样的问题。不过同样的文件我通过Postman调用接口的时候成功删除了

重新测试了下,在用Docker进行部署测试的时候大致有三种情况:

  1. 在Web界面当中直接删除,网页中的图片正常删除消失,本地uploads下对应的文件同样被删除
  2. 用Postman发送图片并删除之后,在网页显示正常删除消失,但是本地uploads下对应的文件并未被删除
  3. 在使用您开发的插件中启用SyncDelete并删除后,PicGo后台提示删除成功,但是网页显示和本地后台文件均未删除

不排除有我个人因为刚接触工具不熟悉的情况导致的失误 😕

@hellodk34
Copy link
Author

@HalcyonAzure 感谢你帮忙测试。

20220330171809

PicGo lankong 插件 SyncDelete 选项打开同步删除图床文件就是调用的删除图片 api(和上面使用 postman 工具调用删除接口一样),各种参数我也确认过好几遍,接口也返回了 true,就是没能删除图片。暂时还不太清楚是为何没有删除成功(抽空再检查一下代码与 api 说明页面认真核对下。

至于你有说

用Postman发送图片并删除之后,在网页显示正常删除消失,但是本地uploads下对应的文件并未被删除

这好像也很怪 😿️

@hellodk34
Copy link
Author

hellodk34 commented Apr 1, 2022

@HalcyonAzure 请教一下我用 postman 调 API 上传文件总是遇到错误

Warning: Missing boundary in multipart/form-data POST data in Unknown on line 0
{"status":false,"message":"\u670d\u52a1\u5f02\u5e38\uff0c\u8bf7\u7a0d\u540e\u518d\u8bd5","data":{}}

是怎么回事?req headerContent-Type 已经指定成了 multipart/form-data 了,费解啊

postman upload image.png

我自己的 Lsky Pro V2 站

换了 dogimg 点 com 也无法通过 api 上传,不过错误信息不同

dogimg.png

dogimg 点 com

感觉和前置的反向代理服务器有关,比如我的用了 nginx ,nginx 配置不当。或者容器内的 php 或 Apache 配置不当 (本人不是很了解 php 和 Apache -_-)

@HalcyonAzure
Copy link

HalcyonAzure commented Apr 1, 2022

@hellodk34
我的Postman设置大致如下
Authorization:
image
Headers:
image
其中
Content-Typemultipart/form-data; charset=utf-8; boundary=+ Math.random().toString().substr(2))
Acceptapplication/json, text/javascript, */*; q=0.01
Body:
image
发送成功后返回的内容大致为:
image

@HalcyonAzure
Copy link

@HalcyonAzure 请教一下我用 postman 调 API 上传文件总是遇到错误

Warning: Missing boundary in multipart/form-data POST data in Unknown on line 0
{"status":false,"message":"\u670d\u52a1\u5f02\u5e38\uff0c\u8bf7\u7a0d\u540e\u518d\u8bd5","data":{}}

是怎么回事?req headerContent-Type 已经指定成了 multipart/form-data 了,费解啊

postman upload image.png

我自己的 Lsky Pro V2 站

换了 dogimg 点 com 也无法通过 api 上传,不过错误信息不同

dogimg.png

dogimg 点 com

感觉和前置的反向代理服务器有关,比如我的用了 nginx ,nginx 配置不当。或者容器内的 php 或 Apache 配置不当 (本人不是很了解 php 和 Apache -_-)

另外上图发的两个报错应该是相同内容,“\u670d\u52a1\u5f02\u5e38\uff0c\u8bf7\u7a0d\u540e\u518d\u8bd5”这个用Unicode转码为中文后对应的内容就是"服务异常,请稍后再试",我自己昨天遇到这个报错后Google搜了下,在Content-Type加上charset=utf-8; boundary=+ Math.random().toString().substr(2))就可以自动转码成中文了 XD

@hellodk34
Copy link
Author

@HalcyonAzure

Content-Type 加上 charset=utf-8; boundary=+ Math.random().toString().substr(2)) 就可以自动转码成中文了

确实如此,感谢。

我上面使用的是 insomnia 和 vscode 里的扩展 Thunder Client,,刚刚我重新下载回 Postman 上传了一遍,居然一直 400 bad request, 我不知道哪里出了问题,和你的配置完全一样,可能是 nginx 配置问题。

@wisp-x wisp-x added the bug Something isn't working label Apr 1, 2022
@wisp-x
Copy link
Collaborator

wisp-x commented Apr 1, 2022

@hellodk34 @HalcyonAzure 很抱歉,这是程序中的一个 bug,目前已修复,将在下个版本中发布。

@wisp-x wisp-x closed this as completed in dec4e6f Apr 1, 2022
@hellodk34
Copy link
Author

实际上我还没测试到 通过接口调用删除图片 API,web 上图片成功消失但物理文件并没有被删除 这个地步。原因是我使用 postman 或 lankong 插件调用删除图片接口时写错了 URL。

20220401170449

感谢 @HalcyonAzure 的帮助,更感谢兰空作者大大的工作。👍🏻

现 PicGo 插件 lankong 已发布 v1.0.6,可实现同步删除。

@hellodk34
Copy link
Author

ps: 我通过 web 删除了图片并没有触发 我的图片 页面自动刷新,是 nginx 或 apache 配置问题吗?

之前版本是 V2,现在升级到了 V2.0.3 不存在这个问题了(之前 2.0 最初的版本可能有问题,现在最新版没有问题,非常棒)。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants