I'm trying to post data. Everything works fine, but I don't know why I'm getting two requests OPTIONS & POST
POST:
OPTIONS:
Here's the code:
const url = 'http://rest.learncode.academy/api/johnbob/myusers';
export function postUsers(username, password) {
let users = {
username,
password,
};
return{
type: "USERS_POST",
payload: axios({
method:'post',
url:url,
data: users,
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
})
}
}
Non-simple CORS requests via AJAX are pre-flighted. Read more about it here. This is a browser behavior and nothing specific to axios. There's nothing inherently wrong with this behavior and if it's working for you, you can just leave it.
If you insist on getting rid of it, there are a few ways you can go about:
You can set Access-Control-Allow-Origin: * on your server to disable CORS.
Make your CORS request a simple one. You will have to change the Content-Type header to application/x-www-form-urlencoded, multipart/form-data, or text/plain. Not application/json.
I'd say just leave it as it is if the OPTIONS request is not blocking you.
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 send post request to my API that contains userName and password in the body. When I do that with Postman I can get a response which has a body contains a token.
But when I send the same request with fetch in fronted I get a responce with an empty body.
My feth is here:
async function login(){
await fetch('/auth/login',
{
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(
{
'userName' : userName,
'password' : password,
}
)
}
).then(
res => {
console.log(res)
localStorage.setItem('Authorization',JSON.stringify(res))
}
).catch(
err => {
console.log("Erorororor: " + JSON.stringify(err))
}
)
}
What is the problem?
I changed my code to
.then(res => return res.text()).then(data => console.log(data)).catch(...)
and now I can get the result which I want.
TLDR Solution
It's caused by some header settings from the server side (For example, setting Access-Control-Allow-Origin: *
twice will likely cause this issue). By tuning the headers you can fix it.
Details
I met the same issue. It's NOT caused by javascript code as the browser itself doesn't get body either, but headers and cookies are got.
By expanding the timing tab you can see a warning showing the request is not finished!
But the postman can get the body:
When
The same code works in the past. It came out recently. I'm not sure what's changed as there are many things changed, for example, the browser version, the nodejs version upgraded, etc.
Fixed
By tunning the headers in the server side fixed the problem.
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).
I am working on an angular.js project with one of my friends, and we are running into a specific CORS (cross origin request) issue. The server is a Microsoft ASP.NET restful API, and I am using angular.js with Node.js.
We enabled CORS on the server side, and are able to get responses for everything else, accept the user login, which we are using ASP.NET Identity with. We always get the same error which I will post bellow, as well as the POST from the Client side. So basically my question is, does any one have an idea on how to fix this? Thanks!
XMLHttpRequest cannot load http://lectioserver.azurewebsites.net/api/v1/accounts/login. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'localhost' is therefore not allowed access. The response had HTTP status code 400.
function login(username, password) {
var innerconfig = {
url: baseUrl + "/api/v1/accounts/login",
data: {
username: username,
password: password,
grant_type: "password"
},
method: "POST",
headers:
{
'Accept': 'text/json'
}
};
return $http(innerconfig).then(onSuccess, requestFailed);
function onSuccess(results) {
if (results && results.data) {
$rootScope.access_token = results.data.access_token;
return results.data;
}
return null;
}
}
Try to set the content-type in the headers, this might fix the issue
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
This usually happens because app that provides you token starts before CORS initiates.
Fixing it is very easy. You just need to go to IdentityConfig.cs and inside that there is function called as
public static ApplicationUserManager Create
(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
Insert this following line of code there
context.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
This will enable CORS for Token request.
But problem is when we do this other normal requests will start throwing error since we have granted access origin * twice. Once in identiy and other in cors.
if you run into this error use this if statement on cors code in identity config you just pasted.
if(context.Request.ContentType == "text/plain")