为什么Laravel的getMimeType()方法将文件标识为"application/octet-stream"?当文件具有“音频/mpeg"的类型属性时? [英] Why does Laravel's getMimeType() method identify a file as "application/octet-stream" when the file has the type attribute of "audio/mpeg"?

查看:1132
本文介绍了为什么Laravel的getMimeType()方法将文件标识为"application/octet-stream"?当文件具有“音频/mpeg"的类型属性时?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将MP3文件上传到Laravel应用程序,但是遇到了一个问题,即使该文件的属性设置为音频/mpeg",它也会作为应用程序/八位字节流"上传( .bin)文件.当我尝试使用以下方法在服务器端代码中将文件死掉并转储时:

I'm trying to upload a MP3 file to a Laravel application and have ran into an issue where even though the file has an attribute set to "audio/mpeg" it is uploaded as a "application/octet-stream" (.bin) file. When I try to die and dump the file on the server-side code with:

dd($request->file('file'));

我得到:

UploadedFile {#187 ▼
  -test: false
  -originalName: "CUS12309821-20-AUG-2016-13-48-13.mp3"
  -mimeType: "audio/mpeg"
  -size: 47000471
  -error: 0
  path: "/private/var/folders/c7/6ws0lxy95dd_lhz1k067_zkc0000gn/T"
  filename: "phpyZCsbU"
  basename: "phpyZCsbU"
  pathname: "/private/var/folders/c7/6ws0lxy95dd_lhz1k067_zkc0000gn/T/phpyZCsbU"
  extension: ""
  realPath: "/private/var/folders/c7/6ws0lxy95dd_lhz1k067_zkc0000gn/T/phpyZCsbU"
  aTime: 2016-09-20 12:56:00
  mTime: 2016-09-20 12:56:00
  cTime: 2016-09-20 12:56:00
  inode: 4565593
  size: 47000471
  perms: 0100600
  owner: 501
  group: 20
  type: "file"
  writable: true
  readable: true
  executable: false
  file: true
  dir: false
  link: false
}

看看我使用此方法的方式时,确实的确表明mimeType的文件属性是正确的音频/mpeg"格式.但是,当文件上传后在文件上调用getMimeType()方法时,我得到:

Look at how when I use this method, it does indeed say that the file attribute for mimeType is the correct "audio/mpeg" format. However when I call the getMimeType() method on the file after it's uploaded, I get:

"application/octet-stream"

这是路由方法中的代码:

Here's the code in the routed method:

/**
 * Store a newly created resource in storage.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return \Illuminate\Http\Response
 */
public function store(Request $request)
{
    $file = $request->all();

    $filePath = Storage::putFile('file', $request->file('files'));

    dd($request->file('file')->getMimeType());

    $file['path'] = Storage::url($filePath);
    $file['size'] = Storage::size($filePath);
    $file['type'] = $request->file('file')->getMimeType();

    return $file;
}

这个问题看似独特,因为我使用的是Laravel框架,而其他有此问题的人则使用的是原始PHP.此外,其他人可能会向我们报告的excel文件本身是应用程序/八位字节流,而不是excel文件.最后,我相信这可能是由getMethodType()调用的guess()方法引起的.拥有更多Laravel经验的人可能会证实这一点.

This problem is seemingly unique in that I'm using the Laravel framework, where others with this problem are using vanilla PHP. Additionally, the excel file others may us may have reported itself as a application/octet-stream instead of an excel file. Finally, I believe this may be a issue with the guess() method, which is called by the getMethodType(). Someone with more Laravel experience could probably confirm this.

推荐答案

UploadedFile对象最终从Symfony\Component\HttpFoundation\File\UploadedFile扩展而来,该对象从/The type of the file as provided by PHP获取/设置mimeType.

The UploadedFile object is ultimately extended from Symfony\Component\HttpFoundation\File\UploadedFile which get/sets the mimeType from The type of the file as provided by PHP.

要访问该mimeType,您需要致电$file->getClientMimeType()

To access that mimeType you would need to call $file->getClientMimeType()

但是在Symfony docblock中,该功能建议:

However in the Symfony docblock for the function it suggests:

客户端mime类型是从上传文件的请求中提取的,因此不应将其视为安全值.

The client mime type is extracted from the request from which the file was uploaded, so it should not be considered as a safe value.

对于受信任的mime类型,请改用getMimeType()(它会根据文件内容猜测mime类型).

For a trusted mime type, use getMimeType() instead (which guesses the mime type based on the file content).

但是在您的情况下,$file->getMimeType()应该被信任并从内容中猜测MIME类型,但是它返回的内容似乎无法确定MIME类型,即应用程序/八位字节流"

In your case however $file->getMimeType() which should be trusted and guesses the mime type from the contents, however it returns something as if it cannot determine the mime type, being "application/octet-stream"

其他信息

可以帮助您做出决定.基本上getClientMimeType()会返回由浏览器设置的mime类型.

To help you decide. Basically getClientMimeType() would return the mime type that was set by the browser.

getMimeType调用使用我可以看到的两种不同技术来猜测mime类型:

The getMimeType call guesses the mime type using two different techniques that I can see:

  1. 使用二进制mime类型技术查看以下命令file -b --mime %s 2>/dev/null的输出(如果受支持).

  1. Using a binary mime type technique looking at the output of the following command file -b --mime %s 2>/dev/null if it is supported.

第二种技术是使用finfo_open命令(如果它确实存在于php中).

The second technique is using the finfo_open command if it does exist inside php.

如果您的系统上同时存在1.和2.,从我看来2.将优先考虑,而1.将是后备.

If both 1. and 2. exists on your system, from what I see 2. will take preference, and 1. will be the fallback.

出于个人安全性考虑,我个人倾向于使用getMimeType()的结果.但是,询问浏览器mime类型检测的可靠性如何,以及使用了哪些技术"将是另一个有趣的问题:-)

I personally would favour the results from getMimeType() for security. However, it would be another interesting question to ask "How reliable is browser mime type detection, and what techniques are used" :-)

更新示例

我为您提供一个例子.

对我来说,检查"DropboxInstalled.dmg",这是我的结果:

For me doing a check on a "DropboxInstalled.dmg", here are my results:

  1. 从命令行(终端)使用file -b --mime DropboxInstaller.dmg返回application/octet-stream

使用finfo_open功能

$finfo = new \finfo(FILEINFO_MIME_TYPE);
echo $finfo->file('./DropboxInstaller.dmg');

返回application/x-iso9660-image

这篇关于为什么Laravel的getMimeType()方法将文件标识为"application/octet-stream"?当文件具有“音频/mpeg"的类型属性时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆