办公文件的回形针上传(docx,pptx)正在下载为zip文件?

时间:2012-05-30 01:02:16

标签: ruby-on-rails ruby-on-rails-3 amazon-s3 paperclip mime-types

我正在使用以下文件上传:Rails 3.2,Paperclip(3.0.4),aws-sdk(1.5.2)& jQuery的文件上传

问题是像(pptx)这样的office文件是作为zip文件而不是pptx文件下载的。以下是我在日志中看到的内容:

Started POST
Processing by AttachmentsController#create as JS
  Parameters: {"files"=>[#<ActionDispatch::Http::UploadedFile:0x007fa1d5bee960 @original_filename="test1.pptx", @content_type="application/vnd.openxmlformats-officedocument.presentationml.presentation", @headers="Content-Disposition: form-data; name=\"files[]\"; filename=\"test1.pptx\"\r\nContent-Type: application/vnd.openxmlformats-officedocument.presentationml.presentation\r\n", @tempfile=#<File:/var/folders/rm/89l_3yt93g31p22738hqydmr0000gn/T/RackMultipart20120529-10443-1ljhigq>>]}
.....


SQL (1.4ms)  INSERT INTO "attachments" ("attachment_content_type", "attachment_file_name", "attachment_file_size", "attachment_file_title", "attachment_updated_at", "created_at", "deleted", "room_id", "pinned", "updated_at", "user_id") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING "id"  [["attachment_content_type", "application/zip"], ["attachment_file_name", "test1_1338339249.pptx"], ["attachment_file_size", 150329], ["attachment_file_title", "test1.pptx"], ["attachment_updated_at", Wed, 30 May 2012 00:54:09 UTC +00:00], ["created_at", Wed, 30 May 2012 00:54:09 UTC +00:00], ["deleted", false], ["room_id", 20], ["pinned", false], ["updated_at", Wed, 30 May 2012 00:54:09 UTC +00:00], ["user_id", 1]]
[paperclip] Saving attachments.
[paperclip] saving /development/private/rooms/20/user_uploaded_files/test1_1338339249.pptx
Command :: file -b --mime '/var/folders/rm/89l_3yt93g31p22738hqydmr0000gn/T/RackMultipart20120529-10443-1ljhigq20120529-10443-1lr2yg2'
[AWS S3 200 1.16513 0 retries] put_object(:acl=>:private,:bucket_name=>"cdn-assets-site-com",:content_type=>"application/zip",:data=>#<Paperclip::FileAdapter:0x007fa1d2540170 @target=#<File:/var/folders/rm/89l_3yt93g31p22738hqydmr0000gn/T/RackMultipart20120529-10443-1ljhigq>, @tempfile=#<File:/var/folders/rm/89l_3yt93g31p22738hqydmr0000gn/T/RackMultipart20120529-10443-1ljhigq20120529-10443-1lr2yg2>>,:key=>"development/private/rooms/20/user_uploaded_files/test1_1338339249.pptx") 

注意文件如何作为pptx进入,但是当上传到AWS S3时作为zip文件?

6 个答案:

答案 0 :(得分:12)

好像您没有注册MIME类型。

x(Office 2007+)结尾的Office文件确实是压缩的XML文件任何使用普通MIME类型的内容都会将其视为压缩文件。

Office 2007+文件的MIME类型

| File |                             MIME type                                   |
+------+-------------------------------------------------------------------------+
|.docx |application/vnd.openxmlformats-officedocument.wordprocessingml.document  |
+------+-------------------------------------------------------------------------+
|.xlsx |application/vnd.openxmlformats-officedocument.spreadsheetml.sheet        |
+------+-------------------------------------------------------------------------+
|.pptx |application/vnd.openxmlformats-officedocument.presentationml.presentation|

config/initializers/mime_types.rb文件中,添加必填字段,如下例所示;

"application/vnd.openxmlformats-officedocument.presentationml.presentation", :pptx

具有讽刺意味的是,IE可能难以识别新的MS Office文件,而其他浏览器则认为它们很好。

为了让IE使用这些文件,您需要将mime类型添加到服务器配置中。在Rails中,这是在config/initializers/mime_types.rb

中完成的
Mime::Type.register "application/vnd.openxmlformats-officedocument.wordprocessingml.document", :docx
Mime::Type.register "application/vnd.openxmlformats-officedocument.presentationml.presentation", :pptx
Mime::Type.register "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", :xlsx

如果您的应用程序是通过Apache代理的,并且Apache为您的静态资产提供服务,您还必须根据http://bignosebird.com/apache/a1.shtml

为新的mime类型配置apache(并重新启动)

通常mime类型位于/etc/mime.types,但如果您不确定,请尝试locate mime.types

您可以参考 paperclip adapters

您也可以阅读 Description of the default settings for the MimeMap property and for the ScriptMaps property in IISOffice 2007 MIME types for ApacheUploading docx files with Paperclip and RailsDynamic Word (.docx) Documents in Rails

答案 1 :(得分:10)

事实证明,正如Marc B首先暗示的那样 - 以x结尾的所有Office文档确实都是压缩的XML文件。任何使用普通mimetypes的东西都会认为它是一个压缩文件。

要解决这个问题,你必须register the Office mimetypes with your server。所以,对于你的.pptx文件,你输入

Mime::Type.register "application/vnd.openxmlformats-officedocument.presentationml.presentation", :pptx
在config / initializers / mime_types.rb文件中

或者,如果您必须支持所有Office 2007文件,则可以使用Rack::Mime::MIME_TYPES.merge!()中的{{1}}方法。

答案 2 :(得分:3)

Office格式的'x'版本是ARE zip文件 - zipped xml。因此,任何根据mime类型确定文件扩展名的内容都会将它们视为zip文件。

答案 3 :(得分:3)

日志的Command :: file -b --mime '/var/folders ...部分意味着Paperclip无法通过MIME::Types.type_for检测到mime类型,并且正在回退file命令。

此处的相关代码:https://github.com/thoughtbot/paperclip/blob/5bf0619fe79ffbcaf8f0d8a7aca88b5685aec4b3/lib/paperclip/io_adapters/file_adapter.rb#L16

在这里:https://github.com/thoughtbot/paperclip/blob/5bf0619fe79ffbcaf8f0d8a7aca88b5685aec4b3/lib/paperclip/io_adapters/file_adapter.rb#L71

file命令在无扩展名临时文件上运行,并且它是一个ZIP文件,因为正如其他人所指出的那样,它确实是。

MIME::Types.type_for("test1.pptx")在控制台中正常工作的事实似乎表明original_filename在代码的那一部分中很奇怪,或者MIME::Types.type_for在回形针内部的行为与在控制台中的行为不同

您可以检测宝石的相关部分(通过调试器或在本地副本中投放一些打印件)来查看它看到的内容吗?另外,您是否可以提供有关如何将控制器转换为附件对象的更多详细信息?

答案 4 :(得分:2)

截至2019年,已接受的解决方案无效。

参考找到的解决方案here,我使用以下代码将它们下载为.docx。

[
  ['application/vnd.openxmlformats-officedocument.wordprocessingml.document', [[0, "PK\x03\x04", [[30, '_rels/.rels', [[0..5000, 'word/']]]]]]],
  ['application/vnd.openxmlformats-officedocument.wordprocessingml.document', [[0, "PK\x03\x04", [[30, 'word/']]]]]
].each do |magic|
  MimeMagic.add(magic[0], magic: magic[1])
end

请注意,仅要求'mimemagic/overlay'中的initializers/mimemagic.rb也不起作用,我不得不手动添加模仿类型。

要解决在修复程序之前上传的文件,我只需将它们重新上传到s3。

答案 5 :(得分:1)

对于那些发现仍然无法正常工作的人,较新版本的Paperclip在Paperclip::ContentTypeDetector中具有Newtonsoft.Json.Linq gem依赖关系。你需要用它来注册mime类型。