Can't set customized header value with fetch - reactjs

I want to send API KEY in the headers of my request. I use fetch method like this (I use react and its in shopify module) :
fetch("https://shopify.mysite.fr/shopify/articles/1", {
method: "GET",
mode: "cors",
headers: {
"Content-Type": "application/json",
"x-auth-token":"$2y$13$Kf0P46IM19qsdqk78SuB6CeuFfnonjsdfsdgsdhYvlSsf9uttNOgdjAQnZCz6y"
}
})
.then(res => res.json())
.then(data => {
this.setState({ article: data });
console.log(data);
})
.catch(console.log);
The problem is "x-auth-token" appeared in "access-control-request-headers" field. I just have the name but not the value (the key) and my API respond 401 ...
request headers
What should I do to obtain x-auth-token in the api?

This is the standard behaviour of the CORS enabled requests.
Before an actual call is made (GET with x-auth-token header) the browser is performing CORS preflight. This usually takes a form of additional OPTIONS request with your non-standard headers being sent in access-control-request-headers header, so that during an actual call server would know that it is safe to accept this non-standard header. Your 401 probably means that your API is not configured to accept cross origin calls or that it doesn't now your domain name and therefore prevents you from accessing it.

Related

API cs-cart put request by react and axios

I use react in front-end and cs-cart API in back-end.
In the following code I used axios.put() as follows:
const data = JSON.stringify({
"test1": "val1"
});
const config = {
method: 'put',
url: 'https://example.com/api/product/111',
headers: {
'Authorization': `Basic ${token}`,
'Content-Type': 'application/json'
},
data : data
};
axios(config)
.then(res => {
console.log(res)
});
When sending a request, the browser sends a request with the OPTIONS method, which error: 405
Method Not Allowed returns.
And the original request (PUT) is not sent.
cs-cart is installed on the server. And the react project on localhost
Have you made sure to understand the error correctly i.e
The HyperText Transfer Protocol (HTTP) 405 Method Not Allowed response
status code indicates that the server knows the request method, but
the target resource doesnt support this method.
The server must generate an Allow header field in a 405 status code
response. The field must contain a list of methods that the target
resource currently supports.
Make sure that the server is able to understand how to interpret your request so the clients are able to proceed.
You can look at this in more detail below here.

CORS issue in Axios

I'am Trying to get Data from another source via axios and it causes a CORS issue
if (imgUrl) {
axios
.get(proxyUrl + imgUrl, {
headers: {
"Access-Control-Allow-Origin": "*",
"Content-Type": "application/json",
},
})
.then((response) => {
console.log("response inside orderdetailPageCOntainer", response)
this.setState({binaryData: response.headers["x-final-url"]}, () =>
console.log("bbbbbbbb",this.state. binaryData));
});
// fetch(proxyUrl + imgUrl)
// .then(response => response.text())
// .then(contents => console.log("contents", contents))
// .catch(() => console.log(`Can’t access ${imgUrl} response. Blocked
by browser?`));
}
Follow these steps,
1) First check whether your Api is up.
2) Try to do the request via a postman tool. Cors do not apply for requests made via postman.
3) If the request is successful via postman, then you Api is good. Issue is cors.
4) Then add your front end app's domain as a allowed origin in you Api configuration. They way doing it depends on your Api technology. Read the doc on that.
5) there is no use of the the request Header: "Access-Control-Allow-Origin": "*". At the client side.
Hope this helps,
Cheers
Cross-Origin Resource Sharing (CORS) is a standard that allows a server to relax the same-origin policy. This is used to explicitly allow some cross-origin requests while rejecting others.
So maybe the other server rejecting loading resources from other domains.

Failed to upload data from heroku app. CORS error

I'm trying to fetch my data from a heroku app into Redux, but I think I'm running into a CORS issue. I've been playing with "headers" for a while and still can't figure it out.
This is the exact error:
"Failed to load https://name-app.herokuapp.com/users: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled."
And this is my code:
export function fetchMicros() {
return dispatch => {
const url = "https://name-app.herokuapp.com/users";
return fetch(url, {
method: 'GET',
mode: 'cors',
headers: { 'Content-Type': 'text' },
})
.then(handleErrors)
.then(res => res.json())
.then(micros => {
dispatch(fetchVitamins(micros));
}
)};
};
If you don't have to do any authentication nor need to pass any data, you can do a no-cors request (more information on mdn page).
fetch(url, {
mode: 'no-cors',
})
If you do need cookies or some kind of authentication, then you need to make the server accept your domain and request methods on the preflight response.
In the event that you don't have access to change that on the server, you can create a nodejs server that will handle the calls for you, bypassing any cors checks (only browser cares about cors, servers don't).

React, Fetch-API, no-cors, opaque response, but still in browser memory

I've been trying to make an React site, which would fetch a GET-response from API and print it out to my .html-file. I've managed to fetch the file just right, but i can't access the JSON-data server sends me.
If i use no-cors in my Fetch-request, i get an opaque response containing pretty much nothing, but if i go to Developer tools i can find my data there and read it. If i do use cors, almost same thing. I get an 403-error, but my data is in the browser memory, but my code doesn't print it out. I can find the response from Network in developer tools.
Why does the server give me an error, but still i get my data? And how can i access it, if it's in the browser?
class Clock extends React.Component {
constructor(props) {
super(props)
this.state = {data2: []}
this.apihaku = this.apihaku.bind(this)
}
componentDidMount() {
this.apihaku(),
console.log("Hei")
}
apihaku () {
fetch('https://#######/mapi/profile/',
{method: 'GET', mode:'no-cors', credentials: 'include',
headers: {Accept: 'application/json'}}
).then((response) => {
console.log(response);
response.json().then((data) =>{
console.log(data);
});
});
}
render() {
return <div>
<button>Button</button>
</div>
}}
ReactDOM.render(
<Clock />,
document.getElementById('content')
)
EDIT: Error images after trying out suggestions
https://i.stack.imgur.com/wp693.png
https://i.stack.imgur.com/07rSG.png
https://i.stack.imgur.com/XwZsR.png
You're getting an opaque response, because you're using fetch with mode: 'no-cors'. You need to use mode: 'cors' and the server needs to send the required CORS headers in order to access the response.
Fetch is doing exactly what the documentation says it's supposed to do, from Mozilla:
The fetch specification differs from jQuery.ajax() in two main ways:
The Promise returned from fetch() won’t reject on HTTP error status
even if the response is an HTTP 404 or 500. Instead, it will resolve
normally (with ok status set to false), and it will only reject on
network failure or if anything prevented the request from completing.
By default, fetch won't send or receive any cookies from the server,
resulting in unauthenticated requests if the site relies on
maintaining a user session (to send cookies, the credentials init
option must be set). Since Aug 25, 2017. The spec changed the default
credentials policy to same-origin. Firefox changed since 61.0b13.
So you need to use CORS, otherwise you get an opaque response (no JSON), and then 403 to me suggests that you haven't authenticated properly. Test your API with Postman, if I had to take a guess I'd say the API isn't sending the cookie because it's a GET request, so no matter how well you set your headers on the client it won't work. Try it as a POST instead. GET requests should really only be used to drop the initial HTML in the browser. I think for your headers use these, include the creds that the API sends and allow the domain to be different.
mode: "cors", // no-cors, cors, *same-origin *=default
credentials: "include", // *same-origin
Try this and see where is the error happening i believe in the parsing but lets check and see
fetch(https://#######/mapi/profile/, {
method: "GET",
headers: {
"Content-Type": "application/json"
},
credentials: "include"
})
.then((response) => {
console.log(response);
try {
JSON.parse(response)
}
catch(err){
console.log("parsing err ",err)
}
})
.catch((err)=>{
console.log("err ",err)
});
I had a similar issue, this kind of problem happend when a HTTP port try to send request to a HTTPS endpoint, adding a "mode:'no-cors'" doesn't do what is SOUND doing but rathere when the documentation says.
I fixed the issue by allowing in my API Application for calls from my HTTP port
(i'm using a .net 6 as an API in debugging mode, my code look like this https://stackoverflow.com/a/31942128/9570006)

Authentication Error when using mode: no-cors using fetch in React

I am building a React app that is pulling different stats from services for our internal developers (commits, tracked hours, etc)..
I am using fetch to grab API data from Harvest, a time tracking app. According to their docs, you can use basic HTTP authentication. When I use the app Postman, all is well and I can see the response just fine. Initially I used:
getHarvest(){
// Set Harvest Headers
const harvestHeaders = {
method: 'GET',
headers: {
'Authorization': 'Basic xxxxxxxxxxxxxxx=',
'Content-Type': 'application/json',
'Accept': 'application/json',
'Cache-Control': 'no-cache',
}
};
fetch('https://factor1.harvestapp.com/projects/', harvestHeaders)
.then( response => response.json() )
.then( projects => {
// Do some stuff
} )
}
This gives me an error in the console:
Fetch API cannot load https://myaccount.harvestapp.com/projects/.
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:3000' is therefore not allowed
access. The response had HTTP status code 404. If an opaque response
serves your needs, set the request's mode to 'no-cors' to fetch the
resource with CORS disabled.
So with that feedback I changed the function to look like this:
getHarvest(){
// Set Harvest Headers
const harvestHeaders = {
method: 'GET',
mode: 'no-cors',
headers: {
'Authorization': 'Basic xxxxxxxxxxxxxxx=',
'Content-Type': 'application/json',
'Accept': 'application/json',
'Cache-Control': 'no-cache',
}
};
fetch('https://factor1.harvestapp.com/projects/', harvestHeaders)
.then( response => response.json() )
.then( projects => {
// do stuff
} )
}
But that results in an Authentication error:
GET https://myaccount.harvestapp.com/projects/ 401 (Unauthorized)
I'm not sure how I can get the response correctly. Am I doing something wrong? It seems odd to me that using the app Postman works but this doesn't. Thoughts? Thanks!
It doesn’t seem like the Harvest API is meant to be used with XHR or Fetch from Web applications.
At least their docs don’t mention anything about using their API from XHR or Fetch, nor do those docs mention anything about Access-Control-Allow-Origin nor CORS in general.
Instead the docs give examples of using the API with curl and with the Postman REST Client.
And trying examples in the docs like below, the response has no Access-Control-Allow-Origin.
curl -H 'Content-Type: application/xml' -H 'Accept: application/xml' \
-u "user#example.com:password" https://example.harvestapp.com/account/who_am_i
So it seems like the answer is: You can’t access the Harvest API with XHR/Fetch from a Web app.
It works in Postman because Postman is not bound by the same-origin policy browsers enforce to prevent Web apps running in a browser from making cross-origin requests unless the site/endpoint the request is made to has opted in to using CORS (which it seems Harvest hasn’t opted into).

Resources