title: Why does Axios send my POST request with Content-Type application/x-www-form-urlencoded when using a string as the request body?
body: <p>I found this interesting behavior with axios while making POST requests. I am sending URLs that the user types in to my Spring RestController which accepts the request body as a String. It looks like this:</p>
  <pre class="lang-java prettyprint-override"><code>@PostMapping(&quot;user/{userId}/link&quot;)
  public ResponseEntity&lt;UserLinkDTO&gt; addUserLink(
      @PathVariable(value = &quot;userId&quot;) Integer userId, @RequestBody String url) {
      ...
  }
  </code></pre>
  <p>On the front end, my axios request looks like this:</p>
  <pre class="lang-js prettyprint-override"><code>const saveUserLink = async (userId: number, url: string): Promise&lt;UserLinkDTO&gt; =&gt; {
    return axiosInstance.post(`user/${userId}/link`, url))
    .then(r =&gt; r.data)
  );
  </code></pre>
  <p>When I send some arbitrary URLs (with <code>=</code> in them) like these:</p>
  <p><code>https://www.google.com/search?client=firefox</code></p>
  <p><code>https://www.yahoo.com/somePage?key=value&amp;hello=world</code></p>
  <p>the Spring POST method receives the <code>url</code> exactly as it was sent.</p>
  <p>However, when I send some URLs like this (without any <code>=</code> in them):</p>
  <p><code>https://www.google.com</code></p>
  <p><code>https://www.yahoo.com/somePage</code></p>
  <p>my Spring POST method receives the <code>url</code> with <code>=</code> appended to them! So the links are received as:</p>
  <p><code>https://www.google.com=</code></p>
  <p><code>https://www.yahoo.com/somePage=</code></p>
  <p>I noticed the requests are being sent with <code>Content-Type: application/x-www-form-urlencoded</code> in my Network tab. However, based on <a href="https://www.npmjs.com/package/axios#using-applicationx-www-form-urlencoded-format" rel="nofollow noreferrer">axios docs</a>, all requests should be serialized to JSON which would imply being sent with <code>Content-Type: application/json</code>. All the other requests I'm using are sent with <code>Content-Type: application/json</code>. It's only this one that gets converted to <code>Content-Type: application/x-www-form-urlencoded</code>.</p>
  <p>I edited my axios post request to include some custom headers so I could change the <code>Content-Type</code> back to <code>application/json</code>:</p>
  <pre class="lang-js prettyprint-override"><code>const saveUserLink = async (userId: number, url: string): Promise&lt;UserLinkDTO&gt; =&gt; {
    return axiosInstance.post(`user/${userId}/link`, url, {
      headers: {
        'Content-Type': 'application/json',
      }
    })
    .then(r =&gt; r.data)
  );
  </code></pre>
  <p>My Spring POST method is now able to receive the URLs above exactly as provided, regardless of if they have <code>=</code> in them or not. There is no longer an extra <code>=</code> appended to the links without any <code>=</code>.</p>
  <p>Why is it that axios seems to change the <code>Content-Type</code> from <code>application/json</code> to <code>application/x-www-form-urlencoded</code> when providing a string as the request body?</p>