Reputation: 27
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:
@PostMapping("user/{userId}/link")
public ResponseEntity<UserLinkDTO> addUserLink(
@PathVariable(value = "userId") Integer userId, @RequestBody String url) {
...
}
On the front end, my axios request looks like this:
const saveUserLink = async (userId: number, url: string): Promise<UserLinkDTO> => {
return axiosInstance.post(`user/${userId}/link`, url))
.then(r => r.data)
);
When I send some arbitrary URLs (with =
in them) like these:
https://www.google.com/search?client=firefox
https://www.yahoo.com/somePage?key=value&hello=world
the Spring POST method receives the url
exactly as it was sent.
However, when I send some URLs like this (without any =
in them):
https://www.google.com
https://www.yahoo.com/somePage
my Spring POST method receives the url
with =
appended to them! So the links are received as:
https://www.google.com=
https://www.yahoo.com/somePage=
I noticed the requests are being sent with Content-Type: application/x-www-form-urlencoded
in my Network tab. However, based on axios docs, all requests should be serialized to JSON which would imply being sent with Content-Type: application/json
. All the other requests I'm using are sent with Content-Type: application/json
. It's only this one that gets converted to Content-Type: application/x-www-form-urlencoded
.
I edited my axios post request to include some custom headers so I could change the Content-Type
back to application/json
:
const saveUserLink = async (userId: number, url: string): Promise<UserLinkDTO> => {
return axiosInstance.post(`user/${userId}/link`, url, {
headers: {
'Content-Type': 'application/json',
}
})
.then(r => r.data)
);
My Spring POST method is now able to receive the URLs above exactly as provided, regardless of if they have =
in them or not. There is no longer an extra =
appended to the links without any =
.
Why is it that axios seems to change the Content-Type
from application/json
to application/x-www-form-urlencoded
when providing a string as the request body?
Upvotes: 0
Views: 1572
Reputation: 361
the default content-type in axios is 'application/x-www-form-urlencoded'
//https://github.com/axios/axios/blob/master/lib/defaults.js
var DEFAULT_CONTENT_TYPE = {
'Content-Type': 'application/x-www-form-urlencoded'
};
//...
utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {
defaults.headers[method] = utils.merge(DEFAULT_CONTENT_TYPE);
});
while when request's data is an Object, axios sets contentType to 'application/json':
if (utils.isObject(data)) {
setContentTypeIfUnset(headers, 'application/json;charset=utf-8');
return JSON.stringify(data);
}
Upvotes: 1