lowercase00
lowercase00

Reputation: 2556

“No 'Access-Control-Allow-Origin' header is present” error for some requests but not others

I have a VueJS app running on S3 that is served by a Flask-powered API running on AWS Elastic Beastalk.

The problem

When making some requests, I get the following:

Access to XMLHttpRequest at 'https://api.myflaskapi.net/blueprint/get_info?date=2019-01-01' from origin 'https://app.myvuejsapp.net' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

What I've done so far

In my __init__.py file, initialized by the app factory in Flask I have set CORS(app, support_credentials=True) as the example on this link. With that, I would hope that basically any request would have the CORS heading, so I wouldn't have any policy blocking my frontend requests.

The ideal scenario would be to only allow requests from https://app.myvuejsapp.net, so I tried using CORS(app, support_credentials=True, origins=['https://app.myvuejsapp.net']) but also without success.

I've also tried making one CORS instance for each of my blueprints with CORS(myblueprint) for each .py route file (I have one for each blueprint), also without success.

The strange thing is, I do have one function on Vue that runs when the app is mounted that works just fine. I can't see any difference between this and other functions that won't work.

Example of working function (returns true or false from the backend):

      checkDB() {
        const path = this.base_url + 'blueprint/check_db'
        axios.get(path, this.token)
          .then(checkupd => {
            this.isupdated = Boolean(checkupd.data);
            if (this.isupdated == true) {
              this.update_msg = "Database up to date."
              this.loading = false
              this.finished = true
            } else {
              this.update_msg = "WARNING: Check DB status."
            }
          })
          .catch(error => {
            console.log(error)
          })
      },

Example of non-working function (returns a XLS from the backend):

      getSalesFrom(file) {
        const fs = require('fs')
        const FileDownload = require('js-file-download');
        const path = this.base_url + `blueprint/get_sales?date=${this.date}`
        axios.get(path, {
            headers: 
              {
                "X-Access-Token": "mytoken",
                "Content-Type": "application/json"
              },
            responseType: 'blob'
          })
          .then(response => {
            const content = response.headers['content-type'];
            download(response.data, 'text.xlsx', content)
          })
          .catch(error => {
            console.log(error)
          })
        this.export_dialog = false
      }

S3 CORS Configuration XML

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>Authorization</AllowedHeader>
    <AllowedHeader>Content-Length</AllowedHeader>
    <AllowedHeader>Access-Control-Allow-Origin</AllowedHeader>
    <AllowedHeader>X-Access-Token</AllowedHeader>
</CORSRule>
</CORSConfiguration>

Any ideas on what I might be doing wrong? I've been reading for a while, but can't seem to find a solution for what it seems a pretty simple problem... Maybe I should mess with the S3 bucket permission configuration?

Thanks.

Upvotes: 1

Views: 1847

Answers (2)

sideshowbarker
sideshowbarker

Reputation: 88046

Any time you run into a case where you’re seeing a “No 'Access-Control-Allow-Origin' header is present” message for some requests but not others, use the Network pane in browser devtools to check the HTTP status code of the response.

Almost always what you’re going to find is that the HTTP status code in those cases is a 4xx or 5xx error instead of the expected 200 OK success response.

The only reason you see the “No 'Access-Control-Allow-Origin' header is present” message is those cases is, the Access-Control-Allow-Origin header typically isn’t going to get added to 4xx and 5xx errors. Part of the reason is, in the 5xx case especially, the cause can be a server failure that occurs before the server ever gets around to running your application code. Along with that, most servers by default won’t add application-set response headers to 4xx and 5xx errors; instead by default they only add them to 2xx success responses.

So anyway, what you want to do is, look at the server logs on the server side (for the server you’re sending the request to) and see what messages the server is logging about the cause of whatever problem it is that makes the server end up sending that 4xx or 5xx error response.

Upvotes: 1

Adrian Krupa
Adrian Krupa

Reputation: 1937

As I understand correctly you host your Vue.js application from S3.

You need to include CORS headers in your S3 buckets. Without them the browser will block all requests to your Flask application. You are making requests to api.myflaskapi.net from app.myvuejsapp.net so you need configure CORS in app.myvuejsapp.net.

You can read documentation how to set CORS in S3 here and here.

To configure your bucket to allow cross-origin requests, you create a CORS configuration, which is an XML document with rules that identify the origins that you will allow to access your bucket, the operations (HTTP methods) that will support for each origin, and other operation-specific information.

You can add up to 100 rules to the configuration. You add the XML document as the cors subresource to the bucket either programmatically or by using the Amazon S3 console. For more information, see Enabling Cross-Origin Resource Sharing (CORS).

Upvotes: 1

Related Questions