Not sending correct header in netuno - javascript

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());

Related

React Native - I can't get a response from my FETCH, but my api does get the data i post

I tried many things, it will only POST to the api when it has "mode: no-cors" and no headers.
I am now trying with mode: 'cors', because i've read that i shouldn't use 'no-cors' because of security reasons. BUT, i do have to remove the headers or else it won't POST the data.
Here's the code:
signUp: async(email, password)=> {
let values = {
firstname: "pruebaNombre",
lastname: "pruebaApellido",
email: email,
password: password
}
const config = {
method: 'POST',
mode: 'cors',
// headers: {
// 'Access-Control-Allow-Origin':'*',
// 'Content-Type': 'application/json'
// },
body: JSON.stringify(values),
}
const response = await fetch('http://localhost/rest-api-authentication-example/API/create_user.php', config);
const data = await response.json();
console.log(data);
}
The console.log(data) should be a json with a message saying "user was created", but i get these errors:
Access to fetch at 'http://localhost/rest-api-authentication-example/API/create_user.php' from origin 'http://localhost:19006' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header has a value 'http://localhost/rest-api-authentication-example/' that is not equal to the supplied origin. Have the server send the header with a valid value, or, if an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Failed to load resource: net::ERR_FAILED
Uncaught (in promise) TypeError: Failed to fetch
The data does get posted on my server, but i can't get a the response from the fetch.
EDITED.- These are my headers on my server side:
header("Access-Control-Allow-Origin: http://localhost/rest-api-authentication-example/");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Methods: POST");
header("Access-Control-Max-Age: 3600");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
The 'Access-Control-Allow-Origin' header has a value 'http://localhost/rest-api-authentication-example/' that is not equal to the supplied origin
Try adding proxy: "http://localhost:${PORT}" to your React-Native package.json where PORT is your server port

Cant enable CORS on the server side NodeJS

I can't enable CORS on the server-side. My frontend and backend servers have different ports. Here is how server-side is implemented:
http
.createServer(function (req, res) {
// .. Here you can create your data response in a JSON format
// const { headers, method, url } = req;
// let body = [];
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Request-Method', '*');
res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET');
res.setHeader('Access-Control-Allow-Headers', '*');
if (req.method === 'OPTIONS') {
res.writeHead(200);
res.end();
return;
}
// const responseBody = { headers, method, url, body: JSON.stringify(data) };
response.write('{asd: 123}'); // Write out the default response
res.end(); //end the response
})
.listen(port);
And I call the fetch function from the frontend-side like this one:
fetch('http://localhost:3035', {
method: 'POST',
mode: 'same-origin', // no-cors, *cors, same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'include', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json',
// 'Content-Type': 'application/x-www-form-urlencoded',
},
body: JSON.stringify(line), // body data type must match "Content-Type" header
})
.then((response) => response.json())
.then((data) => console.log(data))
.catch((error) => console.log(error));
But still getting errors:
Security Error: Content at http://localhost:3030/ may not load data from http://localhost:3035/.
TypeError: "NetworkError when attempting to fetch resource."
You explicitly disallowed CORS on the client side by setting mode: 'same-origin' instead of the default mode: 'cors'.
To quote the docs:
same-origin — If a request is made to another origin with this mode set, the result is simply an error. You could use this to ensure that a request is always being made to your origin.
Since http://localhost:3035/ is another origin than http://localhost:3030/, the result is, exactly as designed, "simply an error".
Set it to mode: 'cors' or remove mode entirely since cors is the default anyway.
On a side note, Access-Control-Request-Method is a request header in the preflight request, not a response header. You should remove it.
As mentioned in the comments: For a credentialed request to work, you cannot use an allowed origin of *. If you don't want to hardcode the expected origin at this point though, you can avoid this problem by always returning the origin that the current request comes from, using res.setHeader('Access-Control-Allow-Origin', req.headers.origin).

Error consuming an Endpoint api-football.com (CORS related)

I'm trying to consume this endpoint at the api-football.com
Here is their documentation: https://www.api-football.com/documentation-beta#section/Authentication
The error is: Access to XMLHttpRequest at 'https://v3.football.api-sports.io/teams?id=40' from origin 'http://localhost:4200' has been blocked by CORS policy: Request header field x-rapidapi-host is not allowed by Access-Control-Allow-Headers in preflight response.
Here is my code:
httpOptions.headers = new HttpHeaders({
// 'Access-Control-Allow-Origin': '*',
// 'Access-Control-Allow-Methods': 'GET',
// 'Accept': '*/*',
'Content-Type': 'application/json',
'x-rapidapi-host': 'v3.api-football.com',
'x-rapidapi-key': this._publicKey,
});
const url = 'https://v3.football.api-sports.io/teams?id=40';
return this.http.get<any>(url, httpOptions)
.pipe(
catchError(this.handleError('getLiverpool', []))
);
I understand what CORS is, but not how to fix it in this case? I am using Angular 9.
Ehy!
the easiest solution would be to use your back-end as middleware to send the request to the 3rd party API. This and other more complex alternatives here
the problem is the server, it needs to accept your request.
If once deployed they are going to be in the same server, you can disable cors in your browser, if not, you have to update the server

Ionic can't get open cors

I am trying to get API data from live server in ionic android app but it returns this error:
Access to XMLHttpRequest at 'https://example.com/api/categories/' from origin 'http://192.168.43.71:8100' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Server settings
Now I am using Laravel for live server which is giving the API here is how I set CORS in my laravel application:
/bootstrap/app.php
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET');
header('Access-Control-Allow-Headers: *');
// rest of the file
due to my setup above I'm getting this result on CORS tester
Ionic settings
So I've been reading how to solve this issue and came cross lots of similar solutions and this is what I add to my ionic.config.json file
"proxies": [
{
"path": "/api/*",
"proxyUrl": "https://example.com/api/"
}
]
Get request (ionic services)
Here is how I request my get method
apiUrl = 'https://example.com/api/categories/';
constructor(private http: HttpClient) { }
getCategories(): Observable<any> {
return this.http.get(`${this.apiUrl}`).pipe(
map(categories => categories)
);
}
Any idea what else should I do to fix this issue?
SOLVED
Thanks to Stephen Romero for pointing the important part of this solution,
based on stephen answer I added this code to my function:
const httpOptions = {
headers: new HttpHeaders({
'Accept': 'application/json, text/plain',
'Content-Type': 'application/json'
})
};
and used it in my get request like:
return this.http.get(`${this.apiUrl}`, httpOptions).pipe(
Now the for header permissions I used (installed) this package for on my laravel app and made config file set as code below:
return [
/*
|--------------------------------------------------------------------------
| Laravel CORS
|--------------------------------------------------------------------------
|
| allowedOrigins, allowedHeaders and allowedMethods can be set to array('*')
| to accept any value.
|
*/
'supportsCredentials' => false,
'allowedOrigins' => ['*'],
'allowedOriginsPatterns' => [],
'allowedHeaders' => ['*'],
'allowedMethods' => ['GET', 'OPTIONS'],
'exposedHeaders' => [],
'maxAge' => 0,
];
FOR those who doesn't use Laravel
Set your headers like this:
if($request_method = 'GET'){
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, OPTIONS');
header('Access-Control-Allow-Headers: Authorization, Expires, Pragma, DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range');
header("Access-Control-Expose-Headers: *");
}
The most important part of this headers is Access-Control-Allow-Headers part, if you simply use * it won't work! you need to set headers name.
Hope it helps.
Update
Forgot to mention in order to avoid error 301 you need to remove / from end of your api url.
// my api (before)
https://example.com/api/categories/
//changed to
https://example.com/api/categories
I solved my issue using these Headers for my API:
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Credentials: true ");
header("Access-Control-Allow-Methods:GET,POST");
header("Access-Control-Allow-Headers: Authorization, Content-Type, Depth, User-Agent, X-File-Size, X-Requested-With, If-Modified-Since, X-File-Name, Cache-Control");
And Angular Http:
//GET data details
getData(authToken){
const httpOptions = {
headers: new HttpHeaders({
'Accept': 'application/json, text/plain',
'Content-Type': 'application/json',
'Authorization': authToken
})
};
//console.log(authToken);
return this.http.get(this.apiGetUrl, httpOptions).retry(3);
}
Like the previous answer, an Options request automatically gets sent with the GET or POST. If you have apache servers, you can echo$headers = apache_request_headers(); to see what is all coming through. Comparison for $_SERVER and Apache here.
In my case, I run if statements:
if(isset($headers["Authorization"]) && isset($headers["Content-Type"])){
//handle get request
}
else{
//handle options request
echo " False,Re-routing Options Request";
}
I would test your HTTP call in the browser and look at dev tools to confirm the requests being sent. I hope this helps!
Perhaps at some point a preflight OPTIONS request is done by the client and since it isn't a listed method in your Access-Control-Allow-Methods it ends up in a CORS issue.
You should try to make a request to your server endpoint with OPTIONS method to check if this is the case, you can use POSTMAN to make this test.
Then try to add the OPTIONS method to the Access-Control-Allow-Methods and check the difference.

fetch request not sending cookies to PHP server

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

Categories

Resources