1

Even though my code is inside one of my components in Vue, the problem is with Axios, let me explain why. So, I'm trying to get some information, like this:

axios.get('http://localhost:8181/roles/1',  
  {
    headers: {
      'Api-Token': 'tokenTOKEN',
      'Content-Type': 'application/json'
    }
  }
)
.then(response => {console.log(response)})
.catch(response => {
  console.log(response);
})

So, yes, I'm importing Axios correctly. Yes, I know we should not be sending a Content-Type header in a GET request. However, I already read the RFC 7231 and it doesn't say is impossible, is just not common. So, we want to send a Content-Type header in my request.

So, how do I know it doesn't work? Well, one of my middlewares in my Lumen API goes like this:

<?php

namespace App\Http\Middleware;

use Closure;

class JsonVerifier
{
    public function handle($request, Closure $next)
    {
        if($request->isJson())
        {
            return $response = $next($request);
        }
        else
        {
            return response('Unauthorized.', 401);
        }
    }
}

I tried to use Postman to send that specific GET request, and it works. I tried to use fetch() like this:

var miInit = { method: 'GET',
               headers: {
                 'Api-Token': 'tokenTOKEN',
                 'Content-Type': 'application/json'
             },
             mode: 'cors',
             cache: 'default' };

fetch('http://localhost:8181/roles/1',miInit)
.then(function(response) {
  console.log(response);
})

and it works! In both cases (with Postman and fetch()) my API returns the desire data.

However, when I try with Axios, I get a 401 response with the "Unauthorized" word, meaning that Axios didn't send the header correctly.

Now, the question. Is there any other way to send headers in an axios GET request? How can I force Axios to send the headers no matter what as it seem to be case with fetch() and Postman?

Kenny Barrera
  • 170
  • 1
  • 12
  • You're sending a GET request. It'll never **be** JSON. Have you considers the `Accepts` header and `$request->wantsJson()` function instead, which is what's actually intended for this scenario? – ceejayoz Jun 05 '19 at 17:41
  • You should be able to it similar to how `fetch` does it... https://stackoverflow.com/a/47916965/10431732 – Matt Oestreich Jun 05 '19 at 17:47
  • @MattOestreich Nope. Axios (correctly) prevents this in the case of a `Content-Type` header and a data-less request like a `GET` or an empty `POST`. https://github.com/axios/axios/blob/2ee3b482456cd2a09ccbd3a4b0c20f3d0c5a5644/lib/adapters/xhr.js#L112 – ceejayoz Jun 05 '19 at 17:50
  • @ceejayoz - ahh I read the question too quickly - I thought it was stripping all of the headers... Makes perfect sense to me why they would strip it, though! – Matt Oestreich Jun 05 '19 at 19:10

1 Answers1

2

Axios automatically (as it should) removes the Content-Type header if you're sending a request without a body, as you do with any GET request.

https://github.com/axios/axios/blob/2ee3b482456cd2a09ccbd3a4b0c20f3d0c5a5644/lib/adapters/xhr.js#L112

// Add headers to the request
if ('setRequestHeader' in request) {
  utils.forEach(requestHeaders, function setRequestHeader(val, key) {
    if (typeof requestData === 'undefined' && key.toLowerCase() === 'content-type') {
      // Remove Content-Type if data is undefined
      delete requestHeaders[key];
    } else {
      // Otherwise add header to the request
      request.setRequestHeader(key, val);
    }
  });
}

You're probably looking for the Accepts header and $request->wantsJson() (or acceptsJson()) instead.

ceejayoz
  • 165,698
  • 38
  • 268
  • 341