I'm sending post-request from front using axios
var data = {
key1: value1,
};
axios.defaults.xsrfCookieName = 'csrftoken';
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN";
axios({
method: 'post',
url: 'my_url',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json; charset=utf-8'
},
data: JSON.stringify(data),
}).then(function (response) {
console.log(response);
});
But on django-backend I got bytes object b'{"key1":"value1"}'
Is there a way to get a json object on the backend? Or do I need to decode the request?
You don't need to use JSON.stringify with Axios. Axios handles it internally. Just send the plain javascript object to the backend like this
axios({
method: 'post',
url: 'my_url',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json; charset=utf-8'
},
data: data,
})
If you do use stringify, Axios takes that string as JSON and stringifies it again internally, that why you Django is not able to decode it.
EDIT
As per your comment on the question, I can see you are using a simple Django view to handle the request. Django views use WSGIRequest object as their request parameter. Because JSON is sent as the request body, they do nothing to it (do not parse) and present original data as it is. that's why you are seeing bytes object as request.body. You can manually parse it using json module from python standard library like this.
request.data = json.loads(request.body)
Or if you want more API compatible request object, I recommend using api_view decorator from Django rest framework like this
#api_view(http_allowed_methods=['post'])
def func(request):
pass
It will wrap your request with Request object from rest_framework.request module which will handle all parsing for you and present parsed data as request.data. You can read more about it here.
Related
I have a React application where I am changing POST method to GET with the request body as it is. It works fine with POST request however when I change the method to GET, it gives me error-
message: "org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public
My Front End Code-
export const setData = (getData) => dispatch => {
axios({
method: 'GET',
url: 'http://localhost:8080/api',
headers: {
'Content-Type': 'application/json'
},
data: getData
})
.then (response => {
dispatch({
type: API_DATA,
payload: response.data
})
dispatch({
type: SET_SEARCH_LOADER,
payload: false
})
})
.catch(function(error) {
})
}
Can someone let me know what I am missing here. As per my understanding, http allows to have a request body for GET method.
As per my understanding, http allows to have a request body for GET method.
While this is technically true (although it may be more accurate to say that it just doesn't explicitly disallow it), it's a very odd thing to do, and most systems do not expect GET requests to have bodies.
Consequently, plenty of libraries will not handle this.
The documentation for Axois says:
// `data` is the data to be sent as the request body
// Only applicable for request methods 'PUT', 'POST', and 'PATCH'
Under the hood, if you run Axios client side in a web browser, it will use XMLHttpRequest. If you look at the specification for that it says:
client . send([body = null])
Initiates the request. The body argument provides the request body, if any, and is ignored if the request method is GET or HEAD.
If you want to send parameters with get request in axios, you should send parameters as params.
If you want to set "Content-type":"application/json" and send params with get request, you should also send an empty data object.
For example:
const AUTH_TOKEN = 'Bearer token'
const config = {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': AUTH_TOKEN,
},
data: {},
params: {
"post_id": 1
}
}
axios.get("http://localhost/api/v1/posts/", config)
This is not axios, the error origniates from the java backend you're talking to. The public field in your request body is missing.
If you just want to send the data as parameters (which would be odd), pass it using params instead of data (as shown here: https://github.com/axios/axios#example).
I personally don't think your API should support GET with a request body (talk to the devs and ask for documentation).
I am using the fetch() API in JavaScript to retrieve information from my flask backend server. I test the same URL and endpoint in postman, and I receive the response body. However, when I perform the same POST through fetch() and process the Response using async/await, I get body: undefined on the client side. Below is the code:
const result = await fetch(`${BACKEND_URL}/auth`, {
method: "POST",
body: newUserBasicString, // some payload
headers: {
"Content-type": "application/json",
},
});
console.log(JSON.stringify(result));
BACKEND_URL is a forwarded ngrok https url. Why am I receiving no body?
You still need to handle the data returned by the fetch api, as be default it does not know how to handle the body. If you want to do it inline this should return what you want.
const result = await fetch(`${BACKEND_URL}/auth`, {
method: "POST",
body: newUserBasicString, // some payload
headers: {
"Content-type": "application/json",
},
}).then(response => response.json())
// .json() for application/json response
// .text() for application/text response
console.log(JSON.stringify(result));
I have a React application where I am changing POST method to GET with the request body as it is. It works fine with POST request however when I change the method to GET, it gives me error-
message: "org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public
My Front End Code-
export const setData = (getData) => dispatch => {
axios({
method: 'GET',
url: 'http://localhost:8080/api',
headers: {
'Content-Type': 'application/json'
},
data: getData
})
.then (response => {
dispatch({
type: API_DATA,
payload: response.data
})
dispatch({
type: SET_SEARCH_LOADER,
payload: false
})
})
.catch(function(error) {
})
}
Can someone let me know what I am missing here. As per my understanding, http allows to have a request body for GET method.
As per my understanding, http allows to have a request body for GET method.
While this is technically true (although it may be more accurate to say that it just doesn't explicitly disallow it), it's a very odd thing to do, and most systems do not expect GET requests to have bodies.
Consequently, plenty of libraries will not handle this.
The documentation for Axois says:
// `data` is the data to be sent as the request body
// Only applicable for request methods 'PUT', 'POST', and 'PATCH'
Under the hood, if you run Axios client side in a web browser, it will use XMLHttpRequest. If you look at the specification for that it says:
client . send([body = null])
Initiates the request. The body argument provides the request body, if any, and is ignored if the request method is GET or HEAD.
If you want to send parameters with get request in axios, you should send parameters as params.
If you want to set "Content-type":"application/json" and send params with get request, you should also send an empty data object.
For example:
const AUTH_TOKEN = 'Bearer token'
const config = {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': AUTH_TOKEN,
},
data: {},
params: {
"post_id": 1
}
}
axios.get("http://localhost/api/v1/posts/", config)
This is not axios, the error origniates from the java backend you're talking to. The public field in your request body is missing.
If you just want to send the data as parameters (which would be odd), pass it using params instead of data (as shown here: https://github.com/axios/axios#example).
I personally don't think your API should support GET with a request body (talk to the devs and ask for documentation).
I have a React application where I am changing POST method to GET with the request body as it is. It works fine with POST request however when I change the method to GET, it gives me error-
message: "org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public
My Front End Code-
export const setData = (getData) => dispatch => {
axios({
method: 'GET',
url: 'http://localhost:8080/api',
headers: {
'Content-Type': 'application/json'
},
data: getData
})
.then (response => {
dispatch({
type: API_DATA,
payload: response.data
})
dispatch({
type: SET_SEARCH_LOADER,
payload: false
})
})
.catch(function(error) {
})
}
Can someone let me know what I am missing here. As per my understanding, http allows to have a request body for GET method.
As per my understanding, http allows to have a request body for GET method.
While this is technically true (although it may be more accurate to say that it just doesn't explicitly disallow it), it's a very odd thing to do, and most systems do not expect GET requests to have bodies.
Consequently, plenty of libraries will not handle this.
The documentation for Axois says:
// `data` is the data to be sent as the request body
// Only applicable for request methods 'PUT', 'POST', and 'PATCH'
Under the hood, if you run Axios client side in a web browser, it will use XMLHttpRequest. If you look at the specification for that it says:
client . send([body = null])
Initiates the request. The body argument provides the request body, if any, and is ignored if the request method is GET or HEAD.
If you want to send parameters with get request in axios, you should send parameters as params.
If you want to set "Content-type":"application/json" and send params with get request, you should also send an empty data object.
For example:
const AUTH_TOKEN = 'Bearer token'
const config = {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': AUTH_TOKEN,
},
data: {},
params: {
"post_id": 1
}
}
axios.get("http://localhost/api/v1/posts/", config)
This is not axios, the error origniates from the java backend you're talking to. The public field in your request body is missing.
If you just want to send the data as parameters (which would be odd), pass it using params instead of data (as shown here: https://github.com/axios/axios#example).
I personally don't think your API should support GET with a request body (talk to the devs and ask for documentation).
How do I submit complex Json object along with a file upload?
I can do a simple json object successfully, only fails with a complex json:
e.g. [file] + { simple: object } -- okay
e.g. [file] + {some: {complex: 'asdf'}, object:['str1','str2']} -- fails
//here is the simple json data
var params = {simple: 'jsonData'};
//here is the header to enable json stuff
var headers = {
'Content-Type': 'application/json',
'Accept': 'application/json, text/javascript, */*',
'dataType': 'json'
};
//assume we have some files in that html form
var files = fi.button.fileInputEl.dom.files;
form.submit({
url: '/some/api',
waitMsg: 'Uploading your file...',
headers: headers,
params: params,
success: function(a, b) {
//done...
}
});
The code above fails when params is a complex Json object with more than one layer. I am using ExtJs, for those who uses JQuery I guess it is html form so my question would be the same across different js libs.
When doing file uploading, Ext does a form post to a hidden iframe, so you need to parse the data as such.