Fetch answer empty due to the preflight? - javascript

I have an webapp react.js / redux / webpackt / es6... and an api in go with mux from gorilla.
When I make call with the function below my header is empty and content too.
I'm using this package in my webapp to make calls
"isomorphic-fetch": "^2.2.1",
My call example
export function Login(userData) {
return dispatch => {
fetch(API + '/login', {
method: 'post',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: userData.email,
password: userData.password,
}),
})
.then(response => {
console.log(response);
console.log(response.statusText);
console.log(response.status);
console.log(response.headers);
console.log(response.headers.get("Authorization"));
console.log(response.json());
return response.json()
if (response.status >= 200 && response.status < 300) {
console.log(response);
dispatch(LoginSuccess(response));
} else {
const error = new Error(response.statusText);
error.response = response;
dispatch(LoginError(error));
throw error;
}
}).then(function(json) {
console.log('parsed json' + json)
})
.catch(error => { console.log('request failed', error); });
}
In the beginning I had a problem with cors How to handle preflight CORS requests on a Go server I used this solution
We can look the call inside of the console :
login OPTIONS 200 fetch auths.actions.js:38 352 B 1 ms
login POST 200 json Other 567 B 82 ms
When I look inside of my POST Header response I have :
HTTP/1.1 200 OK
Access-Control-Allow-Headers: Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, PATCH, DELETE
Access-Control-Allow-Origin: http://localhost:3000
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0NTQ3NTcxNjEsInVzZXJfaWQiOiI1NmI1YjZlOTFhZTMzYjAwMDFhYmE1MTQifQ.WGoTMxm6OuN24Olwr93J3pND9dFLCtG5MyiRbqLWeD244JtDzq0bGgQMixeZxyuxwGK3u8KhyWD7Rr6iZAGNpA
Content-Type: application/json
Date: Sat, 06 Feb 2016 11:12:41 GMT
Content-Length: 2
So the response handle my preflight information not my POST ? Because there is nothing inside of the response.headers and response.headers.get("Authorization")
There is something wrong ?

I had the problem that my headers were sent, correctly received (chrome's network tab correctly shows me all the sent headers), but I couldn't access them in js (response.headers was empty). As described in Fetch get request returns empty headers, this happened because the server did not set the Access-Control-Expose-Headers header, resulting in the needed headers not to be exposed to js.
So the solution is to add this header on the server and voilà, now the headers are accessible in js:
Access-Control-Expose-Headers: <header-name>, <header-name>, ...
The header takes a comma-separated list of header-names to be exposed to the browser.
For additional info on why this header is needed, see Why is Access-Control-Expose-Headers needed?

Related

Content type 'text/plain;charset=UTF-8' not supported in fetch js ti api spring boot

I'm trying to send an http request using fetch to my backend but it's returning this error even though I'm sending an application/json header,
the content that needs to reach the api is a json
front-end code
let user_ = 'teste';
let email_ = 'teste#email.com';
let pass_ = 'teste';
let button_submit = document.getElementById('mySubmit_signup');
let headers = new Headers();
headers.append('Accept', 'application/json');
headers.append('Content-Type', 'application/json');
headers.append('Access-Control-Allow-Origin', '*');
headers.append('Access-Control-Allow-Credentials', 'true');
button_submit.addEventListener('click', async function(){
try {
await fetch('http://localhost:8080/users', {
mode: 'cors',
method: 'POST',
body: JSON.stringify({
name: user_,
email: email_,
password: pass_
}),
})
.then(
response => response.json()
)
.then(
data => console.log(data)
)
} catch (error) {
console.log(error);
}
});
ATT:
i add header but i receive "Access to fetch at 'http://localhost:8080/users' from origin 'http://localhost:7777' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled."
try {
await fetch('http://localhost:8080/users', {
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
},
body: JSON.stringify({
name: "user_",
email: "mail_#email.com",
password: "pass_"
}),
})
.then(
response => response.json()
)
.then(
data => console.log(data)
)
} catch (error) {
console.log(error);
}
};
req();
You are passing a string to body. This means fetch will automatically add a Content-Type request header saying that you are sending plain text.
Your server side code is expecting JSON and is rejecting your so-called plain text with an error.
You need to explicitly add the correct header to say that you are sending JSON.
headers: {
'Content-Type': 'application/json',
},
Aside Do not add 'Access-Control-Allow-Origin': '*', to your request headers. This is a response header and has no business being on the request. Adding it will create additional problems.
Adding an application/json content type to the request will make it preflighted.
You quoted an error mentioning a preflight request. The error state may have been caused by your incorrect extra header (see the aside above) or it might be that your server isn’t set up to support any preflight request.
If the latter then you need to adjust the server-side code to response to the preflight request (which is OPTIONS rather than POST) to give permission to the browser to make the POST request you want to make.

401 Unauthorized REST API in lightning web component salesforce

I'm trying to execute query using REST API, in a lightning web component.
the request in Postman returning result with success (enabling Follow Authorization header)
but in the JavaScript in lightning web component it returns 401 Unauthorized
the code in the java script is a follow :
let sessionId = 'tokken';
let baseUrl = window.location.origin;
let header = {
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization": "Bearer " + sessionId,
};
if (sessionId) {
let options = {
method: "GET",
mode: 'no-cors',
redirect: 'follow',
headers: header,
};
fetch(baseUrl + '/services/data/v50.0/query/?q=SELECT+name+from+Account', options).then((response) => {
console.log(JSON.stringify(response));
if (!response.ok) {
// throw Error(JSON.stringify(response));
} else {
return response.json();
}
}).then((repos) => {
console.log(repos, repos);
});
}
am I missing something ?
Since you can not pass the value Authorization to no-cors mode, you will need to add CORS configuration in your SalesForce as safe endpoint where they let you make a call.
You can not send Authorization header with "no-cors" mode.
mode: "no-cors"only allows a limited set of headers in the request:
Accept
Accept-Language
Content-Language
Content-Type with a value of application/x-www-form-urlencoded, multipart/form-data, or text/plain

how to get response header in angular 8

Hey i have implemented an api which is a GET request
now what i want is Response Header values but only some of them are showing in the api reponse but in network tab every value is showing
i dont know what is the problem
this is my Http service
pendingResultData(payload: Payload, headerConfig?: {}) {
const params = payload
? {
type: payload.type,
data_scopes: payload.data_scopes,
observe: 'response',
...headerConfig
}
: { observe: 'response', ...headerConfig };
const reqUrl = '/api/data_capture';
return this.timerService.timer(this.httpService.getFullResponse(reqUrl, params));
}
this is my interceptor
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.idToken = this.authService.getAccessToken() || '';
// cloning original request and set/add new headers
const authReq = req.clone({
headers: this.idToken
? req.headers
.set('Authorization', `Bearer ${this.idToken}`)
.set('Access-Control-Allow-Origin', '*')
.set('Content-Type', 'application/json')
.set("Access-Control-Expose-Headers", "*")
: req.headers,
params: req.params
});
return next.handle(authReq);
}
now the headers are coming in response header you can see in Screen shot
i want total, current-page, per-page but headers i am getting in api response are
headers: "content-length: 194
content-type: application/json; charset=utf-8
cache-control: max-age=0, private, must-revalidate"
i wanna know am i doing something wrong and if this a backend problem or not?
any help?
thanks
You can access these by user response.headers.get() method. e.g:
this.httpService.getFullResponse(reqUrl, params).subscribe(response=> {
console.log(response.headers.get('per-page'));
});
i think you have to add your custom headers to "access-control-expose-headers" in the backend response. In your screenshot from above it looks that their are not in the list.
(https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers)
https://github.com/angular/angular/issues/5237#issuecomment-441081290

javascript fetch is not posting to rest api endpoint while postman is doing

I have a rest api endpoint and I am checking it using POSTMAN which is posting correctly. But, when I am doing it using JAVASCRIPT FETCH, I am not able to post it. Below is my code for fetch:
const { inputAOI, wktForCreation } = this.state
fetch('http://192.168.1.127:8080/aoi/', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ userName: 'fuseim', aoiName: inputAOI, wkt: wktForCreation }),
mode: 'no-cors'
}).then(function (response) {
if (response.ok) {
return response.json()
} else {
throw new Error('Could not reach the API: ' + response.statusText)
}
}).then(function (data) {
console.log({ data })
}).catch(function (error) {
console.log({ error })
})
Below is the image for the request headers.
It is seen in the above image that in Request Headers, the Content-Type is still text/plain but I am sending application/json as shown in above fetch code.
Check the response preview in console.
Below is correct POSTMAN request:
As hinted in the comments, the problem is with the mode:"no-cors"
Content-Type is considered a simple header, and should be allowed without cors, but only with the following values:
application/x-www-form-urlencoded
multipart/form-data
text/plain
See: https://fetch.spec.whatwg.org/#simple-header
If you are running the API on the same host/port as the script, you should use mode: "same-origin" alternatively add the host/port that the script is running on as an allowed origin on the API.
For more information about CORS: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
Instead of
headers: {
'Content-Type': 'application/json'
}
you could try:
headers: new Headers({
'Content-Type': 'application/json'
})

Request header field If-None-Match is not allowed by Access-Control-Allow-Headers in preflight response

I am receiving the following error when posting to a REST API using dojo/store/JsonRest.
I am using "X-Requested-With": null in order to avoid preflight request but I still receive this error.
API fully support CORS.
Any idea how can be fixed?
Request header field If-None-Match is not allowed by
Access-Control-Allow-Headers in preflight response.
var store = new JsonRest({
target: 'https://api.xxx.com/data',
headers: {
"Authorization": 'Bearer ' + 'd4c72611fc43ab44a46344d907a2b96964df2c91',
"X-Requested-With": null // no prefligh
}
});
store.get('1-00').then(function (data) {
// ok works here
console.log('get', data)
});
// post request
store.add({name:'test'}).then(function (data) {
// error here
console.log('add', data)
});
I was able to solve this issue using "If-None-Match": null in the headers for JsonRest.
Interesting doc regarding "If-None-Math" can be found on HTTP/1.1 spec.
var store = new JsonRest({
target: 'https://api.xxx.com/data',
headers: {
"Authorization": 'Bearer ' + 'd4c72611fc43ab44a46344d907a2b96964df2c91',
"X-Requested-With": null`, // no prefligh
"If-None-Match": null // solve my issue
}
});
store.get('1-00').then(function (data) {
// ok works here
console.log('get', data)
});
// post request
store.add({name:'test'}).then(function (data) {
// ok works here
console.log('add', data)
});

Categories