I am trying to run a post request from office scripts on an api, but kept getting a failed to fetch error each time when I add :
"Content-type": "application/json"
to the header, once I remove the content-type option or replace its value with something other than "application/json" , then the fetch request works , but returns an error with code 0 and validation error messages indicating that the userName and password ('which are already defined in the body could not be found'):
Below is the code
async function main(workbook: ExcelScript.Workbook) {
const param = {
method: "POST",
headers: {
//"Content-type": "application/json"
},
body: JSON.stringify({ user_id: "uname", password: "pwd"})
};
await fetch("https://testAPI/login/", param).then(response => response.json())
.then(data => console.log(data));
}
error when I run this code with Content-Type header set to 'application/json' (line 33 contains the fetch instruction ):
Line 33: Failed to fetch
Error when I run this code with content-Type set to 'text/plain', other options or completely removing the content-type property from the header :
Also , this same request from postman or power automate with header content-type set to 'application/json' runs successfully , the issue happens only in office script
The issue could potentially have to do with CORS. I had to include CORS headers on the API endpoint I was trying to hit. This may be the issue since you said the status code of the response was 0. Why fetch return a response with status = 0?
I added the following headers to the API route:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-For
Here is my OfficeScript code for reference:
const response = await fetch(url, {
method: 'POST',
body: JSON.stringify(cellData),
headers: {
'Content-Type': 'application/json'
}
})
Related
I created a Formik login form and call to react js fetch method. Add cors in web api end and successfully run in Postman and jquery. How to call "token_type": "bearer", through react js? cors is also enabled in web api and also generate Token successfully. How to call this url https://localhost:44323/token through react js?
My code is
onSubmit={(values) => {
fetch('https://localhost:44323/token', {
method: 'POST',
header: { 'Content-type': 'application/json,multipart/form-data' },
data: JSON.stringify(values)
})
.then(r => r.json())
.then(res => {
console.log(res)
});
}}>
Error messages
The root cause of the problem can be found in the following error message shown:
"Access to fetch at https://localhost:44323/token from origin http://localhost:3000 has been blocked by CORS policy. No Access-Control-Allow-Origin header is present on the requested resource ...."
How to fix the problem?
The problem can be fixed in these ways:
1. Allow the origin (http://localhost:3000) on the server (Recommended)
This can be done by adding the following header to HTTP response on the server side:
Access-Control-Allow-Origin: http://localhost:3000
2. Send Fetch request in the 'no-cors' mode
This can be done by updating the fetch request as follows:
fetch( 'https://localhost:44323/token',
{
method: 'POST',
mode: 'no-cors',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
}
)
.then(response => {
// Code for processing the response
}
)
.catch((error) => {
// Code for handling the error
}
)
More information:
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
I am having a weird problem where when I make a fetch request from the client in development it is not sending the cookies to my server (legacy server that does not run on localhost).
Here is my code for the fetch request:
get( url ) {
return fetch(`${API_URL}${url}`, {
method: 'GET',
headers: headers(),
credentials: 'include'
}).then( parseResponse );
},
Headers is a function that returns the following object:
{
'Accept': 'application/json',
'Content-Type': 'application/json',
'mobile': 'false'
}
Here are the CORS headers I have set on the server (Access-Control-Allow-Origin is dynamic because fetch has issues with *)
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: mobile, Content-Type
Access-Control-Allow-Origin: http://localhost:3000
If I print out $_COOKIE I get back an empty array and when I look at the request I get Provisional headers are shown with no cookies.
Any ideas where I messed up?
Thanks In Advance :-)
I'm making a POST request to a node.js server and I'm having trouble getting it to work. Here's my request:
const headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'this-can-be-anything',
};
export const postVote = (id, vote) =>
fetch(`${uri}/posts/${id}`, {
method: 'POST',
headers,
body: JSON.stringify({options: vote}),
}).then(response => response.json())
.then(data => data)
.catch(err => console.log(err));
The function accepts an 'id' and a 'vote', both strings. The id is being used as part of the URI in the request, and the vote is being supplied as options so the API knows what to do with it. Both of the arguments are being passed correctly:
id = '8xf0y6ziyjabvozdd253nd'
vote = 'upVote'
Here's a link to the GitHub repository for the server/API:
Udacity Readable API
and a screenshot of the network when firing the request:
UPDATE: Added the second screenshot which shows status 200. Though it shows this and appears to have been successful, it still doesn't post to the server and the information stays the same.
What you are looking at is the OPTIONS request in the network tab. For cross origin requests, every request if preceeded by an OPTIONS request which tells the calling client (browser, for example) if those HTTP methods are supported by the remote server for use in crosss origin context.
Check the other requests out. If the OPTIONS request was responded to correctly by the server, the browser must automatically follow up with your POST request
EDIT:
Also, the docs specify the param name to be option whereas in your screenshot it is coming up as options.
Further reading: CORS
Try declaring the headers as such:
var headers = new Headers({
'Content-Type': 'application/json',
'Authorization': 'this-can-be-anything',
})
return fetch(`{SERVICE API URL}`, {
method: 'GET',
headers: {
'userName': "username",
'password': "password",
'content-type': 'application/json'
}
})
.then(response => response.json())
.then(json => dispatch(receivePosts(reddit, json)))
I'm trying to get service API data with authorization headers, but getting 401 - Unauthorized error and the response is Missing Request Headers.
Tried with sending authorization content with body also - getting same error 401 - Unauthorized error.
Edited:
headers: {
'userName': "xyz",
'sessionToken': "xyz................."
}
When I'm checking with Postman client it is working fine, but not with the redux-saga fetch method. Kindly help me for this.
Looks like it's a backend problem - CORS Filter configuration
If the backend is on a different server (could be on the same machine, but in a different Application Server, in other words, on a different port) you have to do some CORS Filters configurations.
The frontend code is running on a server - that means it's an application. Postman is a client, just like Google Chrome or any other browser. That's the explanation why you can do the request without any problem from Postman but unsuccessful from your frontend application.
I guess you enabled the Access-Control-Allow-Origin header on the backend
Now you have to allow your custom headers with Access-Control-Allow-Headers
Whenever I use fetch and I need to add headers to the request I do it this way:
headers: new Headers({
Accept: 'application/json',
Authorization: token,
'Content-Type': 'application/json',
}),
so you might want to try this approach, also in order to debug this issue you might want to check your Netowrk tab and verify which headers are sent with the request.
You need to add an Authorization bearer header.
For instance:
headers = new Headers({
'Authorization': `Bearer ${authorizationCodeOrCredentials}`
});
In your code:
return fetch(`{SERVICE API URL}`, {
method: 'GET',
headers: {
'Authorization': 'Bearer ' + someValue, // Add this line
'userName': "username",
'password': "password",
'content-type': 'application/json'
}
})
.then(response => response.json())
.then(json => dispatch(receivePosts(reddit, json)))
If you are using Linux system & If you have chrome in it...
Run your chrome using following command
/opt/google/chrome/chrome --disable-web-security --user-data-dir
Try now, If everything works fine then it's CORS issue from Backend.
I am trying to add a custom header, X-Query-Key, to a HTTP request using Fetch API or request but when I add this to the header of the request it appears to fail at setting the headers and the Request Method is set to OPTIONS for some reason.
When I remove the header it goes back to being GET as it should do.
Sample code looks like below:
const options = {
url: url,
headers: {
'Accept': 'application/json',
'X-Query-Key': '123456' //Adding this breaks the request
}
};
return request(options, (err, res, body) => {
console.log(body);
});
Try this:
const headers = new Headers({
"Accept": "application/json",
"X-Query-Key": "123456",
});
const options = {
url: url,
headers: headers
};
return request(options, (err, res, body) => {
console.log(body);
});
If that does not solve the issue, it may be related to CORS.
Custom headers on cross-origin requests must be supported by the
server from which the resource is requested. The server in this
example would need to be configured to accept the X-Custom-Header
header in order for the fetch to succeed. When a custom header is set,
the browser performs a preflight check. This means that the browser
first sends an OPTIONS request to the server to determine what HTTP
methods and headers are allowed by the server. If the server is
configured to accept the method and headers of the original request,
then it is sent. Otherwise, an error is thrown.
So you will have 2 requests if use custom headers, first one with method OPTIONS to check if server allows custom headers and after that if the server response is 200 OK and allows your originary request the second one will be send
Working with the Fetch API