12

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

问题是像 (pptx) 这样的办公文件被下载为 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 文件的形式出现?

4

6 回答 6

15

好像您没有注册 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为 apache 配置新的 mime 类型(并重新启动)

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

您可以参考回形针适配器

您还可以阅读IISMimeMap 属性和 ScriptMaps 属性的默认设置说明、Apache 的 Office 2007 MIME 类型使用 Paperclip 和 Rails 上传 docx 文件以及 Rails中的动态 Word (.docx) 文档

于 2012-06-02T04:55:32.313 回答
11

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

为了解决这个问题,您必须在您的服务器上注册 Office mimetypes。所以,对于你的 .pptx 文件,你把

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

在您的 config/initializers/mime_types.rb 文件中。

或者,如果您必须支持所有 Office 2007 文件,您可以使用在此 Stackoverflow 答案Rack::Mime::MIME_TYPES.merge!()中看到的方法。

于 2012-06-01T02:04:50.343 回答
3

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

相关代码:https ://github.com/thoughtbot/paperclip/blob/5bf0619fe79ffbcaf8f0d8a7aca88b5685aec4b3/lib/paperclip/io_adapter/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在回形针中的行为与在控制台中的行为不同。

您能否检测 gem 的相关部分(通过调试器或在本地副本中打印一些内容)以查看它所看到的内容?另外,您能否提供一些有关如何将控制器获取的参数转换为附件对象的更多详细信息?

于 2012-06-03T21:27:24.253 回答
3

Office 格式的“x”版本是 zip 文件 - 压缩的 xml。因此,任何基于 mime 类型确定文件扩展名的东西都将始终将它们视为 zip 文件。

于 2012-05-30T01:04:39.043 回答
3

截至 2019 年,公认的解决方案不起作用。

参考此处找到的解决方案,我使用以下代码将它们下载为 .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'ininitializers/mimemagic.rb也不起作用,我必须手动添加 mimetypes。

为了处理修复之前上传的文件,我只是将它们重新上传到 s3。

于 2019-09-12T13:56:07.183 回答
2

对于那些发现这仍然不起作用的人,较新版本的 PaperclipmimemagicPaperclip::ContentTypeDetector. 您需要使用它来注册 mime 类型。

于 2016-08-05T19:12:10.013 回答