Laravel MIME Validation

2020-07-16 09:19发布

I came across a hassle, regarding validating the upload of JavaScript files using Laravel, where the valdation rule is :

'javascript_file' => 'required|mimes:js'

Which should work as far as i know, since Laravel uses the mime_content_type() to guess the mimes of files, but it doesn't go through, giving me a mime type error when testing with a file with application/javascript mime type

Edit: dd($_FILES) gives

["name"]=> string(7) "data.js"
["type"]=> string(22) "application/javascript"
["tmp_name"]=> string(35) "C:\easyphp\binaries\tmp\php21D0.tmp"
["error"]=> int(0)
["size"]=> int(12253)

Edit 2:

As @searsaw pointed, seems like the validation guess was wrong.

And after digging in validateMimes method in vendor\laravel\framework\src\Illuminate\Validation\Validator.php

and dumping the guess variable dd($value->guessExtension()) i got a txt mime -_- which worked

标签: php laravel
2条回答
▲ chillily
2楼-- · 2020-07-16 09:37

Well, if you're on Laravel >= 5.2, there's a new validation method called mimetypes. So, for your case it could be:

'javascript_file' => 'required|mimetypes:application/javascript,text/plain',
查看更多
We Are One
3楼-- · 2020-07-16 09:49

Ok. So after a thorough dig through the source code of Laravel, I have figured out how this system works. Essentially, Validator breaks down the rule from the parameters you passed and, in this case, sends them to the validateMimes method on the Validator class. This calls a guesser to find out the extension on the file. The guesser first guesses the mime-type by cycling through a bunch of other guessers, which use the finfo PHP extension to guess the mime-type. Once it has the mime-type, it passes that mime-type to an extension guesser that guesses extensions based on an array that has the mime-type as the key and the extension as the value. Then it returns the extension to the original call in the Validator class looks to see if the extension is a value in the array of "parameters" you passed to the rule in the first place. Phew!

Here is the entry the extension guesser is using to guess the extension based on mime-type.

'application/java-archive' => 'jar',
'application/java-serialized-object' => 'ser',
'application/java-vm' => 'class',
'application/javascript' => 'js',
'application/json' => 'json',
'application/jsonml+json' => 'jsonml',

Right in the middle is the javascript entry. From the information I have gathered, I am assuming the mime-type guesser is guessing wrong. It may be interpreting it as a text file and not javascript. Try making sure the file has the right mime-type attached to it.

I tested what a plain javascript file comes up as using mime_content_type(), and it returned text/plain. I'm guessing it's what Laravel is doing too.

Hope this helps!

查看更多
登录 后发表回答