fetch request not sending cookies to PHP server - javascript

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 :-)

Related

Failed to fetch error when using fetch API in office scripts

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'
}
})

fetch() api does not send headers and body in "no-cors" mode?

I am sending POST request like this from browser and it is a cross platform request:
var reg_data = {"name": "John"};
fetch(url, {
method: 'POST',
mode: 'no-cors',
headers: new Headers({
'Content-Type': 'application/json',
'token': 'value'
}),
body: JSON.stringify(reg_data)
})
By the time the request reaches my back-end it does not contain token nor body.
Following is my backend ruby code -
before_action :cors_preflight_check
def cors_preflight_check
headers['Access-Control-Allow-Origin'] = '*'
headers['Access-Control-Allow-Methods'] = 'POST, PUT, DELETE, GET, OPTIONS'
headers['Access-Control-Request-Method'] = '*'
headers['Access-Control-Allow-Headers'] = 'Accept, Content-Type, token'
end
I checked some articles it says it happens as the mode is set to "no-cors" the headers and body is restricted. It works fine with postman, but fails with browser. How do I solve this issue as I want to serve a cross platform request and also access the request headers and body?

Not sending correct header in netuno

I have a backend developed in netuno with api in java, and I want to send a pdf, I have no errors sending an excel, but for some reason I'm not getting it with pdf, my frontend is with react and redux.
The pdf is working when tested in postman (and yes, I know that in postman there are no cors problems),
In the browser if I send a corrupted pdf it is sent to the frontend but if the pdf has the right data it no longer passes in the cors.
I've already put the settings on the server side to receive the correct headers
_header.response.set('Access-Control-Allow-Origin', '*')
_header.response.set('Access-Control-Allow-Methods', 'GET, PUT, POST, DELETE, OPTIONS')
_header.response.set('Access-Control-Allow-Headers', 'Content-Type, Expires, Cache-Control, must-revalidate, post-check=0, pre-check=0, Pragma')
_header.response.set('Access-Control-Allow-Credentials', 'true')
On the java side the pdf is going with the following headers
HttpServletResponse res = proteu.getServletResponse();
res.setHeader("Expires", "0");
res.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
res.setHeader("Pragma", "public");
res.setContentType("application/pdf");
res.setContentLength(baos.size());
OutputStream out = res.getOutputStream();
baos.writeTo(out);
out.flush();
out.close();
My fetch call is like this right now:
import fetch from "cross-fetch";
const FileSaver = require("file-saver");
const qs = require("qs");
fetch("myEndPoint", {
headers: {
accept: "application/pdf",
"content-type": "application/x-www-form-urlencoded"
},
referrerPolicy: "no-referrer-when-downgrade",
method: "POST",
mode: "no-cors",
body: qs.stringify({
...action.value
})
})
.then(resp => resp.blob())
.then(blob =>
FileSaver.saveAs(
blob,
"myPdf" +
new Date(Date.now())
.toLocaleString()
.replace(new RegExp("/", "g"), "")
.split(",")[0] +
".pdf"
)
);
when I execute the code in the browser, that's the way it is:
fetch("myEndPoint", {
credentials: "omit",
headers: { accept: "application/pdf", "content-type": "application/x-www-form-urlencoded", "sec-fetch-mode": "cors" },
referrer: "http://localhost:3000/foo",
referrerPolicy: "no-referrer-when-downgrade",
body:
"myData=foo",
method: "POST",
mode: "cors"
});
And I get the following error code:
Access to fetch at 'myEndPoint' from origin 'http://localhost:3000' has been blocked by CORS policy: 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.
which is strange, considering that all other calls work except this one, and the only difference is the type of document I get.
I have no error on the backend side.
why is chrome editing the mode: "no-cors" for "mode: "cors" ??
if I try to use "sec-fetch-mode: no-cors" in the fetch call header chrome answers:
Refused to set unsafe header "sec-fetch-mode"
The problem was in HttpServletResponse, when you use this on the netuno, it rewrites the header options, so I wasn't sending my previously configured settings, so the correct way to do this is as follows:
BaseService service = new BaseService(proteu, hili);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//my pdf code
service.getHeader().contentTypePDF();
service.getHeader().noCache();
service.getOut().write(baos.toByteArray());

NodeJS HTTPOnly cookie not being sent with fetch function

I'm having problems with cookie authentication between an expressJS server and a VueJS font-end.
When logging in through the site, I successfully get a HTTPOnly Cookie in the set-cookie header:
Screenshot (Ignore the Auth header, using it for testing only)
I also see the cookie in the devTools, and everything looks right too me, I'm not an expert on cookies though so it may not be correct
The problem is when I request the user's settings on another endpoint, the cookie is not sent to the server. The req.cookie object is empty when the this request is handled on the server side.
Here is my fetch code:
const loginOptions = {
method: 'POST',
mode: 'cors',
cache: 'no-cache',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: email,
password: password,
}),
credentials: 'same-origin',
};
const settingsOptions = {
method: 'GET',
mode: 'cors',
cache: 'no-cache',
headers: {
'Content-Type': 'application/json',
},
credentials: 'same-origin',
};
const loginResponse = await fetch(baseUrl + '/login', loginOptions);
const userSettings = await fetch(baseUrl + '/settings', settingsOptions);
I've tried using credentials: "include", without success.
On the express server I'm using cors like this:
app.use(cors({
origin: '*',
credentials: true,
}));
Here is also an example of the second request, the 403 status is set by the server when no cookie is attached to the request.
I've tried setting the domain of the cookie to both localhost and 127.0.0.1 as suggested in another thread. I have left it on localhost for now.
Solved
I had read somewhere that you should add a specific domain value to the cookie when creating it. If I just removed that setting, it sets it automatically I'm guessing, and then it worked! So my guess is that I had set the domain value to the wrong value for what I was trying to do
Your response has access-control-allow-origin: http://localhost:8080 which implies you are making a cross-origin request.
You said:
credentials: 'same-origin',
… which tells your client-side code to only include credentials for same-origin requests.
I read somewhere that Chrome wasn't friendly with cookies and localhost env, maybe it could be that.
https://bugs.chromium.org/p/chromium/issues/detail?id=56211
Furthermore, I had some problems with cookies, express and vueJS some times ago.
Maybe it can help you: SetCookie header not stored
I had read somewhere that you should add a specific domain value to the cookie when creating it. If I just removed that setting, it sets it automatically I'm guessing, and then it worked! So my guess is that I had set the domain value to the wrong value for what I was trying to do

CORS cookie not set in any browser

Response has valid set-cookie header, shows up in response inspector and everything:
But it doesn't set it and therefore doesn't send it with next requests. window.document.cookie returns empty string. Setting path or expires doesn't help, neither does domain=localhost.com;.
Starting to lose my mind after 2 days, Im missing something or it's impossible? I've googled a lot.
Details:
No cookie, CORS related errors
API: https://abc123.api.api-domain.com/
App: http://www.localhost.com/ (set in hosts file, it's actually 127.0.0.1/localhost)
Response headers:
OPTIONS:
Access-Control-Max-Age: '600'
Access-Control-Allow-Headers: 'Content-Type, Cookie'
Access-Control-Allow-Origin: 'http://www.localhost.com'
Access-Control-Allow-Credentials: 'true'
Access-Control-Allow-Methods: 'OPTIONS, POST'
POST:
Access-Control-Allow-Origin: 'http://www.localhost.com'
Access-Control-Allow-Credentials: 'true'
Set-Cookie: 'customCookie=somehash; domain=.localhost.com;'
Fetch function:
return fetch('https://abc123.api.api-domain.com/', {
method: 'POST',
credentials: 'include', // to allow cookies
headers: {
'content-type': 'application/json'
},
body: JSON.stringify(someData),
}).then(res => {
return res.json();
});
Request headers:
Host: "abc123.api.api-domain.com"
Origin: "http://www.localhost.com"
Referer: "http://www.localhost.com/page"

Categories

Resources