Reputation: 1287
I was trying to upload *.svg
images to S3 without specifying any Content-type. This upload works successfully and AWS sets Content-Type as binary/octet-stream by default. Now, when I try to use S3 URL of image in my browser, the browser does not render the image and throws incorrect mime-type warning.
To set the correct mime-type I checked list of Content-type which AWS offers but it does not have "image/svg+xml"
.
So I wanted to know if anyone has tried to upload SVG images to S3? What is the content-type set in that case? Or is there any other compatible Content-type that can be used for uploading SVG images to S3?
Upvotes: 19
Views: 30470
Reputation: 3798
I understood from one of the other answers that you're using s3cmd
to upload the files to S3. The package makes some educated guesses about MIME type for each file based on the file extension (there's a useful explanation here).
There are also a range of options to s3cmd
including the --no-mime-magic
command flag (see https://s3tools.org/usage for info), which helped with CSS and other files, but not with SVG.
To get this to work for my own purposes I had to set a specific Content-Type for only SVG files using include/exclude command flags:
s3cmd sync --content-type 'image/svg+xml' --exclude '*' --include '*.svg' {local source} {S3 bucket URL}
Because I also have other content I had to have a separate s3cmd
command to sync everything else:
s3cmd sync --no-mime-magic --content-type 'image/svg+xml' --exclude '*.svg' {local source} {S3 bucket URL}
Upvotes: 0
Reputation: 4661
I've problems with uploaded files svg to s3 in laravel; but works with next code:
$image = Storage::disk('s3')->put(
$filePath,
file_get_contents($file),
$file->getClientOriginalExtension() === 'svg' ? ['mimetype' => 'image/svg+xml'] : []
);
Upvotes: 0
Reputation: 11
If you want to pass content type static and get file from public path not in request then used this:
$destinationPath = public_path("/images/".$image_name);
if (File::exists($destinationPath))
{
$contents = File::get($destinationPath);
Storage::disk('s3')->put($image_name,$contents,['mimetype' => 'image/svg+xml'],'public');
}
Upvotes: 0
Reputation: 178
For those using an SDK, here's an example code snippet that I used to solve this problem. Im using Javascript (NodeJs). This is to complement the accepted answer above, which is to explicitly define the ContentType as 'image/svg+xml' from the params before uploading.
const params = {
Bucket: 'bucket',
Key: 'key',
Body: stream,
ACL: 'public-read',
ContentType: 'image/svg+xml',
};
s3.upload(params, function(err, data) {
console.log(err, data);
});
Upvotes: 2
Reputation: 13649
As you mentioned, the correct Content-Type for SVG files is "image/svg+xml".
Even if the AWS console does not provide that value in the Content-Type selection field, you can enter it anyway and S3 will accept it.
AWS specifies the following in their API docs for the Content-Type header:
A standard MIME type describing the format of the contents. For more information, go to http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.17.
Type: String
Default: binary/octet-stream
Valid Values: MIME types
Constraints: None
For additional details see http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html
Upvotes: 26