Matt W
Matt W

Reputation: 12423

How to call a server from localhost VueJS with Axios?

I'm trying to call an AWS hosted API from my VueJS app, which is running on my localhost:8080. I have used this blog post to setup the vue.config.js with this block:

module.exports = {
    devServer: {
        proxy: 'https://0123456789.execute-api.eu-west-1.amazonaws.com/'
    },
    ...
}

With this in place, I can use this code to make a GET request to an endpoint at that host:

  this.$axios
    .get('https://0123456789.execute-api.eu-west-1.amazonaws.com/mock/api/endpoint',
    {
      headers: {
        'Content-Type': 'application/json'
    }})

This is because I have configured the AWS API Gateway mock endpoint to return these headers for the OPTIONS method:

Access-Control-Allow-Headers: 'Cache-Control,Expires,Pragma,Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'   
Access-Control-Allow-Methods: 'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'  
Access-Control-Allow-Origin: '*'

However, I cannot make this call:

  this.$axios
    .get('https://0123456789.execute-api.eu-west-1.amazonaws.com/lambda/api/function',
    {
      headers: {
        'Content-Type': 'application/json'
    }})

This endpoint is a Lambda integration and also has an OPTIONS method with the same headers as above.

Why should both endpoints, configured the same way, have different responses for axios?

UPDATE

As advised by @deniz, I have updated the .env.development file to contain:

VUE_APP_API_URI=https://0123456789.execute-api.eu-west-1.amazonaws.com/

I have also updated the axios requests to:

let url = 'mock/api/endpoint'
let headers = {
  headers: {
    'Content-Type': 'application/json',
  },
}

this.$axios
  .get(url, headers)

...and...

let url = 'lambda/api/function'
let headers = {
  headers: {
    'Content-Type': 'application/json',
  },
}

this.$axios
  .get(url, headers)

The result I get for the first GET request is:

200 OK

However the second request's response is:

Access to XMLHttpRequest at 'https://0123456789.execute-api.eu-west-1.amazonaws.com/lambda/api/function' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Upvotes: 0

Views: 2033

Answers (1)

Deniz
Deniz

Reputation: 1503

Your config for your dev env. as a proxy setup is doing nothing else then pretend to be someone else. Thats why you dont get any CORS issues when you work with a proxy. its a kinda bottleneck which acts like "i am someone else, not localhost"

module.exports = {
    devServer: {
        proxy: 'https://0123456789.execute-api.eu-west-1.amazonaws.com/'
    },
    ...
}

from now on all your requests came from this very proxy based URL

https://0123456789.execute-api.eu-west-1.amazonaws.com/

if you try to access the api like this:

this.$axios
    .get('https://0123456789.execute-api.eu-west-1.amazonaws.com/lambda/api/function',
    {
      headers: {
        'Content-Type': 'application/json'
    }})

you should keep in mind that you are already pretend that your proxy is doing his desguise stuff and still acts like its from a other source.

your URL when you call the API looks like this now, if i am not completely wrong:

https://0123456789.execute-api.eu-west-1.amazonaws.com/https://0123456789.execute-api.eu-west-1.amazonaws.com/lambda/api/function

all you have to do is change the axios url in your request to:

this.$axios
    .get('lambda/api/function',
    {
      headers: {
        'Content-Type': 'application/json'
    }})

and try again.


UPDATE

VUE_APP_API_URI=https://0123456789.execute-api.eu-west-1.amazonaws.com/

wrap your URL string into quotes, like this and remove the last slash.

VUE_APP_API_URI='https://0123456789.execute-api.eu-west-1.amazonaws.com'

thats a common practice to handle .env vars.

2. the CORS error you get is a result of not using proxy anymore. your requesting data from a other source now and this is no allowed on modern browsers like FireFox or Chrome etc.

here you have to handle the server side configs in your API: https://0123456789.execute-api.eu-west-1.amazonaws.com

because if you go like that you need to give your localhost and your backend the permission to handle requests if the requests are made from different sources, like in your case:

i am localhost and i request data from https://0123456789.execute-api.eu-west-1.amazonaws.com

normally this is forbidden and is a highly risk on security

But the solution is... As you did before in your AWS API Access-Control-Allow-Origin: '*' is the important part which handles your "CORS" issues.

make sure it is setup correct and works as intended. maybe play around with that and set localhost instead of * (allow for all)

3. i highly recommend you to use the proxy way on development and use the non proxy way only for production, and just allow CORS for your frontend only.

Upvotes: 2

Related Questions