【问题标题】:best way for managing uploaded files in my editor?在我的编辑器中管理上传文件的最佳方式?
【发布时间】:2019-03-15 00:30:27
【问题描述】:

我正在开发一个社交博客,它有一个内置 JavaScript 的编辑器,用于由用户创建博客。我最大的问题之一是上传文件及其限制。现在,为了自动保存用户帖子,我将同时上传到服务器的图像存储起来。但问题是当用户从编辑器中删除图像时,因为:

  • 请求数量可能过多(即使有很多)
  • 在 Ckeditor 中我有一个上传程序,但没有从服务器中删除它(或者至少我不知道如何)
  • 最后是自动保存的好主意(?)

我的编辑器是 ckeditor5 的定制版本,为了上传文件,我使用了一个像这样的上传适配器:

export default class UploadAdapter {
    constructor(loader, article) {
        this.loader = loader;
        this.article = article;
    }
    upload() {
        return new Promise((resolve, reject) => {
            let image = new FormData();
            let url = '/articles/imageUpload';
            image.append('upload', this.loader.file);
            image.append('token', this.article.token);

            axios.post(url, image)
                .then(response => {
                    console.log(response);
                    if (response.data.uploaded) {
                        resolve({
                            default: response.data.url,
                        });
                    }
                    else {
                        reject(response.data.error.message);
                    }
                }).catch(error => {
                console.log(error);
            });
        });
    }
}

【问题讨论】:

  • 6 点赞和 3 颗星,似乎是一个热门话题。恭喜。 “但问题是当用户从编辑器中删除图像时”会出现什么问题?
  • 我们错过了您服务器端的一些信息,但我认为您需要一种方法来唯一地识别上传的带有哈希的图像,并在您的服务器端使用一种方法来删除它
  • 感谢您的支持,我试图澄清我的问题@kerbholz
  • @kerbholz 是的,我认为这是一个常见问题,我的应用程序使用不同的堆栈但相同的功能 ala 在编辑器中上传图像,但是当用户删除它时,我会发生不必要的上传,因为一旦用户插入它它被上传
  • @Badgy 实际上,这就是问题 :)) session 可以在这里选择吗?我的意思是一切都保存在会话中,最后通过上传最后一个版本上传。安全吗?

标签: php laravel vue.js ckeditor


【解决方案1】:

看起来你只需要一个额外的隐藏输入,记录所有上传成功的图像,并在用户发布表单后在编辑器中与图像的 url 进行一些比较,然后你就会得到图像列表已删除。
我希望我能清楚地表达我的意思。

【讨论】:

    【解决方案2】:

    恕我直言,首先你应该定义你的目标,然后寻找解决方案。

    • 您希望您的用户拥有一个功能丰富的漂亮文件管理器吗?这将允许他们从已上传的图像中进行选择。一个人可以准备和上传图片,其他人只需选择它们并将它们粘贴到编辑器中。
    • 您是否愿意提供拖放解决方案并将这些图像上传到某处而不考虑存储空间?
    • 您是否需要跟踪已编辑内容的更改?
    • 是否允许最终用户重复使用已上传的文件?

    根据需要管理从内容中删除的图像可能会很棘手。例如,如果您想跟踪更改并允许用户在其他帖子中重复使用上传的图像 - 在从存储中删除任何图像之前,您应该检查所有帖子和所有版本,如果它们不再包含此图像。 OTOH,如果您不关心版本并且不允许用户重复使用图像 - 那么您可以在从内容中删除任何图像后立即删除它。

    现在存储很便宜,所以我不会为保留一些不再使用的额外图像而费心。更重要的是 - 我不会将清理添加到主要流程中。而不是这样 - 创建一个专门的、重复的作业来扫描内容并删除未使用的图像。为了使其更健壮,我会将图像使用情况保存在某种数据库中。这样清理起来会容易很多。

    有开箱即用的付费解决方案,例如 EasyImage(将图像上传、重新缩放和优化到 CDN)或 CKFinder(功能齐全的文件管理器)。

    不过,根据您的需要,您可能仍需要调整这些解决方案。例如,如果您有一个文件管理器,那么如果文件在任何地方使用,您可能希望阻止删除它们。所以可能需要对某些插件进行额外的工作。

    【讨论】:

      【解决方案3】:

      我使用下面的方法将图像嵌入为 base64 而不是上传它们

      class UploadAdapter {
         constructor( loader ) {
            this.loader = loader;
         }
      
         upload() {
            return this.loader.file
                  .then( file => new Promise( ( resolve, reject ) => {
                        var myReader= new FileReader();
                        myReader.onloadend = (e) => {
                           resolve({ default: myReader.result });
                        }
      
                        myReader.readAsDataURL(file);
                  } ) );
         };
      }
      

      【讨论】:

      • base64 是替代方案,但不是最佳实践,因为从长远来看它会影响服务器性能
      【解决方案4】:

      不知道这对你有没有帮助。但我曾经解决这个删除 像这样的图像问题。

      我使用了summernote 编辑器。

      我在插入带有其他内容的图像时遵循的步骤:

      从编辑器收集所有图片

      $images = $dom->getelementsbytagname('img');
      

      在这里,我以 base64 格式接收图像。这就是为什么我需要对它们进行解码并单独存储

      $imagePaths = [];
      foreach($images as $k => $img){
              $data = $img->getattribute('src');
              $check_image = substr($data,0,10);
              if($check_image != "data:image"){
                  continue;
              }
              list($type, $data) = explode(';', $data);
              list(, $data)      = explode(',', $data);
              $data = base64_decode($data);
              $image_name = time().$k.'.png';
              $path = public_path("/").ImagePaths::$BLOG_DETAILS_PICTURE.'/'.$image_name;
              file_put_contents($path, $data);
              $img->removeattribute('src');
              $img->setattribute('src', asset(ImagePaths::$BLOG_DETAILS_PICTURE.'/'.$image_name));
              $imagePaths[] = $path; // This path for store in DB
          }
      

      当我删除或更新内容时,我只是删除了我之前在$imagePaths 数组中收到并存储的所有图像。

      当我处理这个时,我遵循了this 文档

      Here我共享了完整的控制器脚本。

      【讨论】:

        猜你喜欢
        • 2010-09-06
        • 2018-10-04
        • 1970-01-01
        • 2015-06-29
        • 1970-01-01
        • 2015-09-15
        • 2010-09-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多