Laravel S3 File Upload MimeType Issue

2019-07-10 16:32发布

问题:

I'm having a problem with a CSS file being served under the wrong mimetype from S3 via a CDN.

Heres what I've noticed. If I upload the file via my website, the CSS shows at the CDN url, but will not be used by the website (doesn't render the layout) because its coming up as:

Resource interpreted as Stylesheet but transferred with MIME type text/x-asm

If I go right to the S3 bucket and upload directly to it the file renders the CSS as it should and the site layout looks as it should.

This is my upload code in Laravel:

public function upload(Request $request)
{
    $files = $request->file('asset');

    $directoryname = Auth::user()->assetdirectory;
    $userId = Auth::user()->id;
    $userAssets = Auth::user()->assets;
    $file_count = count($files);
    $uploadcount = 0;       
    foreach($files as $file)
    {
        $data = Input::all();
        $rules = array 
        (
            'asset' => 'required'       
            );
        $messages = array
        (
            'asset.mimes' => 'That file type is not allowed.  Please try a .css or .js file type.',
            'asset.required' => 'A file is required.'
            );
        $validator = Validator::make($data, $rules, $messages);
        if($validator->passes())
        {   
            if ($file == null)
            {
                return redirect('upload')->with('errornotice', 'A file is required.');
            }       

            $filename = $file->getClientOriginalName();
            $fileext = $file->getClientOriginalExtension();
            $filesize = $file->getClientSize();
            $mime = $file->getMimeType();
            foreach($userAssets as $asset)
            { 
                if($asset->name == $filename)
                { 
                    return redirect('upload')->with('errornotice', 'A file with that name already exist');
                } 
            }           
            if($fileext != "css" && $fileext != "js")
            {
                return redirect('upload')->with('errornotice', 'That file type is not allowed.  Please try a .css or .js file type.');
            }   
            $contents = file_get_contents($file->getRealPath());
            Storage::put($directoryname . "/" . $filename, $contents);
            $asset = new Asset;
            $asset->name = $filename;
            $asset->user_id = $userId;
            $asset->size = $filesize;
            $asset->extension = $fileext;
            if($fileext == "css")
            {
                $asset->url   = ('<link rel="stylesheet" href="' . 'https://cdn.xxx.io/' . $directoryname . "/" . $filename . '">');
            } else if($fileext == "js")
            {
                $asset->url   = ('<script src="' . 'https://cdn.xxx.io/' . $directoryname . "/" . $filename . '">' . '</script>');
            }
            $asset->save();
            $uploadcount ++;
        }       
    }
    if($uploadcount == $file_count){
        return redirect('dashboard')->with('notice', 'Your files have been added.');
    } 
    else {
        return Redirect::to('upload')->withInput()->withErrors($validator);
    }       

}

I can get the mimetype $mime = $file->getMimeType(); off the file, but I don't have a clue how to send it along with the upload to s3 Storage::put($directoryname . "/" . $filename, $contents);

回答1:

You can tell S3 the MIME type of your file by the optional $config parameter:

Storage::put($directoryname . "/" . $filename, $contents, ['mimetype' => $mime]);

The mime type of css files is text/css.