title: CORS, OPTIONS and PreFlight problems Consuming REST API with Axios in Vue.js
body: <p>I'm developing a front end to a PHP based application that runs a custom management tool. My goal is to use Vue.js to build out the front end and specifically use Axios to make the API calls.</p>
  <ul>
  <li>I'm using a Lightsail server with a public port forward.</li>
  <li>Visual Studio Code with Remote Developer tools installed and connected via SSH to develop on that server rather than my machine.</li>
  <li>Vue CLI 3 to set up my project and choosing the default packages of Babel and Linting.</li>
  <li>Axios is installed via npm.</li>
  </ul>
  <p>Our PHP environment originally allowed me to pass params like user ID, API Key and a query ( while user = x method=get, apikey=x, ) and I could easily consume the data and output it in a v-for and everything worked pretty well. But, it was not a well designed API structure, so we changed the idea that params would be passed, as I did not like passing the API key in the URL and don't like the idea of having to pass a SQL query to get the data. So, my colleague adjusted the API so now we have a URL that is like <a href="https://tunnel.host.com/api/sites/read.php" rel="nofollow noreferrer">https://tunnel.host.com/api/sites/read.php</a>. We'll also have PHP files for the rest of the CRUD operations later. But I need to get past my current problem.</p>
  <p>My research immediately led me to the issue of CORS and I've spent many hours reading about that topic and ultimately feel like it is the issue preventing me from passing the necessary headers to the server and getting access.</p>
  <p>I thought for a while that installing the CORS npm package would help, but that appears to only be for fixing the issue with a locally hosted server environment. ( like using ExpressJS as the server in a dev environment )</p>
  <p>After reading the Mozilla docs regarding CORS I wonder if I need to send preflight headers in an OPTION HTTP request.</p>
  <p>So far I have tried:</p>
  <ul>
  <li>Adding a vue.config.js file with dev server options ( I'll include the code below )</li>
  <li>Using POSTMAN to construct the headers and pass a GET request - which works just fine</li>
  <li>attempting to use the headers key in an Axios object ( code below )</li>
  </ul>
  <p>My colleague who runs the PHP side of things assures me that all of the CORS headers in the files are correct.</p>
  <p>I only have one component being loaded into App.vue called AxiosTest.</p>
  <p>I've edited this post to update my findings.</p>
  <p>By sending the headers as const the request is made as GET</p>
  <pre><code>const config = {
              headers: {
                      &quot;content-type&quot;: &quot;application/vnd.api+json&quot;,
                      &quot;Cache-Control&quot;: &quot;no-cache&quot;,
                      &quot;x-api-key&quot;: &quot;9xxxxxxxxxxxxxxxxxxxxxx9&quot;
              }
          }
          axios.get(
              `https://tunnel.xxxxx.com/api/headers.php?`,{ config
              })
              .then(response =&gt; {
                  this.results = response;
              })
              .catch(error =&gt; {
                  // eslint-disable-next-line
                  console.log(error)
              })
  </code></pre>
  <p>And the header Response</p>
  <pre><code>HTTP/1.1 200 OK
  Server: nginx/1.10.3 (Ubuntu)
  Date: Mon, 08 Jul 2019 19:22:55 GMT
  Content-Type: application/json; charset=UTF-8
  Transfer-Encoding: chunked
  Connection: keep-alive
  Access-Control-Allow-Origin: http://54.x.x.155:8080
  Access-Control-Allow-Credentials: true
  Access-Control-Max-Age: 0
  </code></pre>
  <p>and the Request</p>
  <pre><code>Host: tunnel.xxxxxx.com
  User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:67.0) Gecko/20100101 Firefox/67.0
  Accept: application/json, text/plain, */*
  Accept-Language: en-US,en;q=0.5
  Accept-Encoding: gzip, deflate, br
  Referer: http://54.x.x.155:8080/
  Origin: http://54.x.x.155:8080
  DNT: 1
  Connection: keep-alive
  Cache-Control: max-age=0
  </code></pre>
  <p>However, if I keep the headers object inside of the axios.get function I get it sent as OPTIONS</p>
  <pre><code>axios.get(
              `https://tunnel.xxxx.com/api/headers.php?`,{
                  headers: {
                      &quot;content-type&quot;: &quot;application/vnd.api+json&quot;,
                      &quot;Cache-Control&quot;: &quot;no-cache&quot;,
                      &quot;x-api-key&quot;: &quot;9xxxxxxxxxxxxxxxxxxxxxx9&quot;
                  }
              })
              .then(response =&gt; {
                  this.results = response;
              })
              .catch(error =&gt; {
                  // eslint-disable-next-line
                  console.log(error)
              })
  </code></pre>
  <p>Response</p>
  <pre><code>HTTP/1.1 200 OK
  Server: nginx/1.10.3 (Ubuntu)
  Date: Mon, 08 Jul 2019 19:22:55 GMT
  Content-Type: application/json; charset=UTF-8
  Transfer-Encoding: chunked
  Connection: keep-alive
  Access-Control-Allow-Origin: http://54.x.x.155:8080
  Access-Control-Allow-Credentials: true
  Access-Control-Max-Age: 0
  Access-Control-Allow-Methods: GET, POST, OPTIONS
  Access-Control-Allow-Headers: {cache-control,x-api-key}
  </code></pre>
  <p>Request</p>
  <pre><code>Host: tunnel.xxxxx.com
  User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:67.0) Gecko/20100101 Firefox/67.0
  Accept: */*
  Accept-Language: en-US,en;q=0.5
  Accept-Encoding: gzip, deflate, br
  Access-Control-Request-Method: GET
  Access-Control-Request-Headers: cache-control,x-api-key
  Referer: http://54.x.x.155:8080/
  Origin: http://54.x.x.155:8080
  DNT: 1
  Connection: keep-alive
  Cache-Control: max-age=0
  </code></pre>
  <p>vue.config.js</p>
  <pre><code>module.exports = {
      devServer: {
          public: '54.x.x.x:8080',
          proxy: 'https://tunnel.xxxxxxx.com/'
      }
    }
  </code></pre>
  <p>In the most successful test produced I still receive Invalid CORS origin or invalid API key.</p>