Search code examples
javascriptvue.jsheaderxmlhttprequestaws-amplify

Couldn't send request to url using XMLHttpRequest


I have started building a Vue.js website, using AWS Amplify for the backend.
In one of the pages, I need to access an external url address, get a response from it, and view the response to the user.
It is important to say that the url is not linked to my website, and it has nothing to do with me. It is totally external and out of my control.

I've tried to access that url many times, using many methods, but so far I receive the following error message every time I'm trying to access the url:

:8080/#/myPage:1 Access to XMLHttpRequest at 'https://~URL~?~DATA~' 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.
xhr.js?b50d:178 GET https://~URL~?~DATA~ net::ERR_FAILED

(I replaced the real url with https://~URL~?~DATA~ and the file name with myPage).

When I'm trying to print the error that is received from the function. I get the following message:

myPage.vue?3266:161 Error: Network Error
                        at createError (createError.js?2d83:16)
                        at XMLHttpRequest.handleError (xhr.js?b50d:83)

When I've tried to access the url with my browser (Google Chrome), it worked well and without any issues. It didn't ask me for any kind of authentication or something like that.
I've tried it as well using Postman, and it worked just fine.
I have experienced this problem only while using my Vue.js website.

This problem happens when I'm running the website from localhost and when I'm running it on host (using AWS Amplify hosting for serverless websites - S3 bucket).
When the website doesn't run on localhost, I still get the same error messages.

Here are some of the methods I tried to access the url with:

  1. Axios

    var config = {
      method: 'get',
      url: 'https://~URL~?~DATA~',
      headers: {
        'Access-Control-Allow-Credentials': true
      }
    };
    
    axios(config)
    .then(function (response) {
      console.log(response);
    })
    .catch(function (error) {
      console.log(error);
    });
    
  2. Fetch

    var requestOptions = {
      method: 'GET',
      redirect: 'follow'
    };
    
    fetch("https://~URL~?~DATA~", requestOptions)
    .then(response => response.text())
    .then(result => console.log(result))
    .catch(error => console.log('error', error));
    
  3. XHR

    var xhr = new XMLHttpRequest();
    xhr.withCredentials = true;
    
    xhr.addEventListener("readystatechange", function() {
      if(this.readyState === 4) {
        console.log(this.responseText);
      }
    });
    
    xhr.open("GET", "https://~URL~?~DATA~");
    
    xhr.send();
    
  4. Request

    var request = require('request');
    var options = {
      'method': 'GET',
      'url': 'https://~URL~?~DATA~',
      'headers': {
      }
    };
    request(options, function (error, response) {
      if (error) throw new Error(error);
        console.log(response.body);
    });
    

I really need your help with this one, as I couldn't find any solution for this all over the web so far.


Solution

  • As far as I understand, this is a CORS Policy error and should be fixed from server side. When you perform an API call, the browser at first sends a pre-flight request to the server. The server responds with some headers, one of the which headers are Access-Control-Allow-Origin header, if this header is set to * or requesting domain, then the actual request will go through, otherwise the api call will get CORS Policy error.

    It's from the server side that one can control which domains can perform API calls to this server.

    You can read more about CORS policy error some workarounds and how to fix it from here, https://medium.com/@dtkatz/3-ways-to-fix-the-cors-error-and-how-access-control-allow-origin-works-d97d55946d9