36

I'm using:

  • Vue 2.0.3
  • vue-router 2.0.1
  • vuex 0.8.2
  • vue-resource 0.7.0

And after trying to login to my page when using remote API, not the locally run one, I get cors error like following

vue-resource.common.js?2f13:1074 OPTIONS 

https://mywebsite/api/auth/login 

(anonymous function) @     vue-resource.common.js?2f13:1074
Promise$1            @     vue-resource.common.js?2f13:681
xhrClient            @     vue-resource.common.js?2f13:1033
Client               @     vue-resource.common.js?2f13:1080
(anonymous function) @     vue-resource.common.js?2f13:1008


XMLHttpRequest cannot load https://mywebsite/api/auth/login. 
Response to preflight request doesn't pass access control check: 
No 'Access-Control-Allow-Origin' header is present on the requested 
resource. Origin 'http://localhost:8080' is therefore not allowed 
access. The response had HTTP status code 415.

Now I have API running in Azure, and since it allows me to test my calls from Postman, I am quite sure the CORS headers are set properly on backend. Not so sure about the Vue and the front.

I have situation like this in config files:

export const API_ROOT = 'https://mywebsite/api/'
export const AuthResource = Vue.resource(API_ROOT + 'auth{/action}')

than i.e I am calling this action like:

login: function (userData) {
    return AuthResource.save({action: 'login'}, userData)
}

Finally as I am checking auth in login via token in vuex submodule I have just a simple header check-up state.

var updateAuthHeaders = () => {
    var token = JSON.parse(localStorage.getItem("auth_token"))
    if (token != null){
        Vue.http.headers.common['Authorization'] = token
    }else{
        Vue.http.headers.common['Authorization'] = null
    }
}

I have tried adding Vue.http.headers.common['Access-Control-Allow-Origin'] = true here, but did not help the case.

Any idea? What am I doing wrong.. I suppose it will not work for other calls also if it doesn't work for login.

desicne
  • 851
  • 2
  • 9
  • 23
  • This doesn't appear to be a CORS issue (as indicated by the 415 error) and there is nothing wrong with your code of client-end. Could you please provide your key code snippet of your backend? – Aaron Chen Nov 30 '16 at 07:15
  • you were totally right! There was my issue with API project not allowing access from the JS inside browsers – desicne Nov 30 '16 at 10:40
  • @desicne can you tell what was your issue? – Darem Aug 22 '18 at 07:28
  • @Darem wasn't a front-end issue. Server setup was not done right at the time. – desicne Aug 23 '18 at 11:33

6 Answers6

36

You face this error when the API url and client url aren't the same. Vue CLI 3 (and in the core of it, Webpack) allows you to proxy your API url to your client url.

Inside vue.config.js file add following lines:

// vue.config.js
module.exports = {
  // options...
  devServer: {
        proxy: 'https://mywebsite/',
    }
}

And then send your ajax calls to http://localhost/api/.

You can read the full article here: How to deal with CORS error on Vue CLI 3?

Negar
  • 649
  • 1
  • 6
  • 9
  • 4
    Thanks! Cool hack! For my case I need to add port when running it in development. ```module.exports = { devServer: { port: 3000, proxy: "http://localhost/api" } }``` – Osh Mansor Oct 04 '19 at 00:32
  • i am getting the following error Proxy error: Could not proxy request / from localhost:8080 to http://localhost:3000/api/auth/. – vithu shaji May 19 '21 at 18:02
  • What is there are some api on the localhost where the vuejs resides, and need to call some api which reside on another server. In that case , @Negar your solution does not works. I have a proejct , which contains larvel api and vuejs. Vuej consuming larvel api fine but when call to other api is made it give cors error. Your implementation give error method not found. – israr Nov 03 '21 at 06:50
8

1) Be sure that server sends Access-Control-Allow-Origin "*" header.

2) Vue.http.headers.common['Access-Control-Allow-Origin'] = true, Vue.http.headers.common['Access-Control-Allow-Origin'] = '*' and etc. don't needed in the client request.

3) Vue.http.options.emulateJSON = true should helps if 1 and 2 points already are ok, but vue-resource fails with status 0. Also, try to remove (if they exist) Vue.http.options.credentials = true and Vue.http.options.emulateHTTP = true.

Nickensoul
  • 435
  • 6
  • 9
7

While you can add Access-Control-Allow-Origin: * to your server response (in this case IIS) but this is very much advised against.

What's happening here is that your client is http://localhost and it is trying to access https://mywebsite/api/ which means they're not from the same origin

If you add Access-Control-Allow-Origin: * you will be allowing the entire world to hit your API endpoint.

I'd suggest making your access control server headers Access-Control-Allow-Origin: *.mysite and make a vhost for your localhost to use dev.mysite or similar.

This will allow your "localhost" to access your API without issues.

You could also add localhost to a whitelist, but this is also not without its own security implications, and it doesn't work everywhere anyway.

So, in short, make a vhost for your localhost that's in the same domain as your REST service and your issue should be resolved.

Once you go live you should remove the *.mysite part and use as specific a domain as possible on your whitelist.

Good luck!

darryn.ten
  • 6,784
  • 3
  • 47
  • 65
2

Greater possibility is that CORS is not enabled on the IIS. This can be enabled by modifying the web.config file in the application root folder in IIS as follows:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
   <httpProtocol>
         <customHeaders>
           <add name="Access-Control-Allow-Origin" value="*" />
         </customHeaders>
   </httpProtocol>

</system.webServer>
</configuration>

Note: This method will allow anyone to reach the API endpoint and hence shouldn't be adopted on a production environment but only on a development environment.

Parthipan Natkunam
  • 756
  • 1
  • 11
  • 16
0

You need a vue.config.js file at the root of your project and inside of the vue.config file you need to define your proxy within a devServer object module.exports = { devServer: { proxy: 'https://exampledomain.com/api/'}};. Within your axios.post you can now make request by simply doing https://exampledomain.com/api/login

image of vue.config.js file

-4

Just attach these in the response to your all API's

res.header('Access-Control-Allow-Origin','*');

res.header('Access-Control-Allow-Methods','GET, POST, OPTIONS, PUT, PATCH, DELETE');

res.header('Access-Control-Allow-Headers','Origin,Content-Type,X-Requested-With,Accept,Authorization');