Applying CORS policies

Last change on 2024-12-03 • Created on 2024-12-02 • ID: ST-C656B

To enable cross-origin requests to your Bucket, you can configure CORS policies. For more information, see the AWS article on cross-origin resource sharing (CORS).

The commands depend on the S3-compatible tool you're using. This how-to guide explains each step with example commands for the AWS CLI and S3cmd. At the time of writing, the MinIO Client did not support PutBucketCors and DeleteBucketCors, see this article.

In the following example, we'll set up a small website hosted on a server that fetches data from a Bucket. We will fetch an image directly via its public URL, and we will fetch data from a JSON file using JavaScript.


  1. Set up an example website

    If you want to follow along with an example website, you can use the following files:

    • Server

      On the server, install a webserver (e.g. nginx) and add the following files:

      /var/www/html/index.html

      Replace <bucket_name> with the name of your Bucket.

      <!DOCTYPE html>
      <html lang="en">
      
      <body>
      
        <h1>Fetching data from a Bucket!</h1>
        <h2>Image:</h2>
        <img src="https://<bucket_name>.fsn1.your-objectstorage.com/image.png" height="100" />
        <br><br>
        <h2>JavaScript:</h2>
        <div class="row" id="content-bucket">
        <!-- Dynamically populated -->
        </div>
        <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
        <script src="js/script.js"></script>
      
      </body>
      </html>
      /var/www/html/js/script.js

      Replace <bucket_name> with the name of your Bucket.

      "use strict";
      
      function listContent(content, contentBucket) {
        $(contentBucket).append(`
                              <h3>${content.title}</h3>
                              <p>${content.text}</p>
                            `);
      }
      
      $(document).ready(() => {
        let contentBucket = $('#content-bucket');
      
        $.getJSON("https://<bucket_name>.fsn1.your-objectstorage.com/data/content.json", contents => {
          contents.forEach(content => {
            listContent(content, contentBucket);
          });
        });
      });

    • Bucket

      Create the following files on the device that has an S3-compatible API tool like S3cmd installed:

      content.json
      [
          {
              "title": "TITLE 1",
              "text":"Text 1"
          },
          {
              "title": "TITLE 2",
              "text":"Text 2"
          }
      ]
      image.png
      wget -O image.png https://picsum.photos/200

      Next, copy the files to your Bucket:

      aws s3 cp content.json s3://<bucket_name>/data/content.json
      aws s3 cp image.png s3://<bucket_name>/image.png
      s3cmd put content.json s3://<bucket_name>/data/content.json
      s3cmd put image.png s3://<bucket_name>/image.png

  1. Prepare the Bucket

    In order for Cross-Origin Resource Sharing (CORS) to work properly with the S3 Bucket, you must set the Bucket visibility to public. You can change the visibility via Cloud Console. Simply navigate to your Bucket and click on "Actions" in the top right. Next, click on "Reset Bucket visibility" and set it to "Public".


  1. Create a CORS configuration

    When you view your website at https://www.example.com, you should already see the image that was fetched from the Bucket. However, the information that is fetched via JavaScript should still be missing. In index.html, the image points directly to the image URL and it is fetched via a simple HTTP GET request. The data from data/content.json, on the other hand, is fetched via JavaScript, which sends an AJAX request. Since this AJAX request is made from the browser to the Bucket (which has a different domain), it is considered a cross-origin request.

    In the CORS configuration of the Bucket, you can specify several different elements. To learn more about them, see the official AWS S3 article "Elements of a CORS configuration".

    Both examples below allow all GET and HEAD requests that come from https://www.example.com.

    Choose one of the options below and create a new file.

    • For AWS CLI, e.g. example-cors.json

      Replace https://www.example.com with your own domain.

      {
        "CORSRules": [
          {
            "AllowedOrigins": ["https://www.example.com"],
            "AllowedHeaders": ["*"],
            "AllowedMethods": ["GET", "HEAD"]
          }
        ]
      }
    • For S3cmd, e.g. example-cors.xml

      Replace https://www.example.com with your own domain.

      <CORSConfiguration>
        <CORSRule>
          <AllowedHeaders>*</AllowedHeaders>
          <AllowedMethod>GET</AllowedMethod>
          <AllowedMethod>HEAD</AllowedMethod>
          <AllowedOrigin>https://www.example.com</AllowedOrigin>
        </CORSRule>
      </CORSConfiguration>

  1. Apply the CORS configuration to your Bucket

    • AWS CLI

      aws s3api put-bucket-cors --bucket <bucket_name> --cors-configuration file://example-cors.json
    • S3cmd

      s3cmd setcors example-cors.xml s3://<bucket_name>

  1. View the CORS rules

    • AWS CLI

      aws s3api get-bucket-cors --bucket <bucket_name>
    • S3cmd

      s3cmd info s3://<bucket_name> | tail -n 3

  1. Verify the connection

    curl \
      -i https://<bucket_name>.fsn1.your-objectstorage.com/image.png \
      -H "Access-Control-Request-Method: GET" \
      -H "Origin: https://www.example.com"

  1. Remove the CORS rules

    • AWS CLI

      aws s3api delete-bucket-cors --bucket <bucket_name>
    • S3cmd

      s3cmd delcors s3://<bucket_name>

You should now also see data retrieved via a cross-origin request on your website.


Next: