在web应用程序中实现功能齐全的媒体上传


Implementation of fully functional media uploading in web application

假设我们有一个处理创建、读取、更新和删除文章的web应用程序,并且每篇文章都应该有图片库。我必须在文章和画廊之间建立一对一的关系,在画廊和媒体之间建立一个对多的关系。

HTML5提供了很多功能,比如多上传,所以我想使用这个优秀的http://blueimp.github.io/jQuery-File-Upload/插件。问题是如何像其他表单的数据一样处理"内存中"的文件上传?

例如,当我们显示创建新文章的页面时,我们应该能够填写文章的数据字段并选择要上传的图像,然后当我们单击保存按钮时,图像应该开始上传,然后表单应该提交。验证失败时,图像仍应显示在前端,但在服务器端不应保存任何链接。

其中一个解决方案是在显示整个表单之前创建类似"创建实体会话临时id"的东西,该id可以用于创建临时目录以保存上载,因此在成功保存表单后,这些图像可以移动到适当的目录,但如何使"创建实体会议临时id"?

我认为另一个解决方案是"使用编辑id"方法,因为我们可以用以前保存的库id处理上传,但有时我无法用库保存新的空白文章,因为数据库中的一些字段不应该为空。

对于我看到的Railshttps://github.com/thoughtbot/paperclip宝石在Readme中说:

回形针旨在作为一个简单的文件附件库的活动记录。它的目的是尽可能简化设置,并尽可能像对待其他属性一样对待文件。这意味着在调用ActiveRecord::Base#save之前,它们不会保存到磁盘上的最终位置,如果设置为nil,也不会被删除。

我的问题是它是如何工作的?

在创建掩码上启用文件上载的问题是,最终会出现孤立文件。这是因为用户能够在不保存实际实体的情况下触发上传。在创建自己的UploadBundle时,我考虑了这个问题一段时间,得出的结论是没有真正合适的解决方案。

我最终是这样实现的:

考虑到我们的问题是由孤立文件引起的,我创建了一个负责管理这些文件的Orphanage。上传的文件将首先与session_id一起存储在一个单独的目录中。这有助于区分不同用户之间的文件。提交表格以创建实际实体后,您可以仅使用会话id从孤儿院检索文件。如果表格有效,您可以将文件从临时孤儿院目录移动到文件的最终目的地。

这种方法有一些陷阱:

  • 孤儿院目录本身应该定期使用cron作业或类似操作进行清理
  • 如果用户将上传文件并选择不提交表单,而是从新表单开始,则新上传的文件将被移动到同一目录中。因此,您将在第一次和获得上传文件后的第二次上传文件

这不是这个问题的最终解决方案,但更多的是一种变通方法。然而,在我看来,它比使用临时实体或基于会话的存储系统更干净。

上面提到的捆绑包在Github上可用,同时支持OrphanagejQuery File Uploader插件。

1up lab/OneupUploaderBundle

我没有亲自处理过这个案子,但我的同事也遇到了类似的难题。她使用

punkave/symfony2文件上传包

这是一个包装jQuery文件上传插件的捆绑包。它还处于早期阶段,很多东西都缺失了,比如赛事,但我们给了它机会。

这就是我们所做的:在newAction()中,我们创建实体,生成唯一的目录ID,并将ID存储在实体中(通过常规的setDirId())。然后我们创建表单,其中包含隐藏字段dirId。

我们通过ajax将文件上传到服务器上的temp-dir,而不是在提交过程中。Ajax请求需要ID。它将文件存储在temp_dir/prefix_ID 中

比这很简单。表格已发送。如果表单有效-将文件从temp移动到dest-dir。如果无效-我们有ID,并且可以显示图像。

但是,我们不会将有关单个文件的信息保存在数据库中的单独表中。每次我们读取与dirId对应的文件夹的内容时。

我知道这不是你想要的解决方案。这只是一个变通办法。