Fetch API cannot load ... No 'Access-Control-Allow-Origin' header - node.js

I got
a rest api deployed on heroku
a react app deployed on heroku
the react app tries to get data from the rest api using whatwg-fetch.
var header = {"Content-Type": "multipart/form-data", 'Origin': 'https://foo.bar', 'Access-Control-Request-Method': 'GET', 'Access-Control-Request-Headers': 'X-Requested-With'};
var options = {method: 'GET', credentials: 'include', headers: header};
fetch('https://myrest.api/foo', options)...
But I can't get any data, it say's
Fetch API cannot load https://foo.bar.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'https://foo.bar' is therefore not allowed access.
The response had HTTP status code 403.
If an opaque response serves your needs, set the request's mode to 'no-cors'
to fetch the resource with CORS disabled.
When I try to get the data with curl it works
curl -H "Origin: https://foo.bar" \
-H "Access-Control-Request-Method: GET" \
-H "Access-Control-Request-Headers: X-Requested-With" \
-X GET --verbose https://myrest.api/foo -D header.txt
and the response header (from the curl command)
HTTP/1.1 200
Server: Cowboy
Connection: keep-alive
Access-Control-Allow-Origin: https://foo.bar
Vary: Origin
Access-Control-Allow-Credentials: true
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Fri, 09 Dec 2016 23:52:57 GMT
Via: 1.1 vegur
Cors is enabled in the spring boot application via #CrossOrigin
Thanks in advance
Best Regards

It seems that you are trying to access from one domain https://foo.bar into another domain at https://myrest.api and that is the reason for that error.
You have 2 options:
1) Merge this 2 apps into one single domain on Heruko, React and the Api apps will be under https://foo.bar domain for example and that will work for you.
2) Allow the client app domain at https://foo.bar to access into your api domain at https://myrest.api by adding "Access-Control-Allow-Origin" header into the api app:
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
next();
});

Related

axios+node.js+cors : even OPTIONS requests don't reach the server

I use the follow first middleware.Due to the token header, the first request to the server is OPTIONS request.For some reason, after reload both the client and server sides, SOMETIMES non-deterministically the request can reach to 'console.log("C")' and send status 200.
app.use(function(req, res, next) {
console.log("A")
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, token");
res.header('Access-Control-Max-Age', String(60 * 60 * 24 * 365));
console.log("B")
if(req.method === 'OPTIONS'){
console.log("C")
res.sendStatus(200);
return res;
}
console.log("D")
next();
});
But subsequent GET or POST requests don't pass because of the message:
...has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
But if to use curl:
curl -I -X OPTIONS http://127.0.0.1:3003/handler
I always get a normal response, which shows all the necessary headers for CORS
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, token
Access-Control-Max-Age: 31536000
Content-Type: text/plain; charset=utf-8
Content-Length: 2
ETag: W/"2-nOO9QiTIwXgNtWtBJezz8kv3SLc"
Date: Sat, 28 Mar 2020 07:24:18 GMT
Connection: keep-alive
With GET, POST requests in a similar way, everything is fine through the curl. But through the browser (using axios) it does not work. Again, it sounds crazy, but sometimes I correct / reload something, the request may even be successful, but when I pull the next handler, for example, / handler2, everything falls again.
Client:
axios.defaults.baseURL = "http://127.0.0.1:3003";
axios.defaults.headers.common["token"] = window.localStorage.token;
window.axios = axios;
axios.post("/user/handler", postData).then(...).catch(...);
Please, don't say about app.use(cors()) or app.options(...) ))
I'm sitting on it already God knows how much...đť—ś tried everything possible. But I think the problem because of the client, but not the server...In the end, for curl it works.
My standard token size is 8 KB, but in Node.js --max-http-header-size is also 8 KB.
To fix this you need to write in package.json:
"scripts": {
"start": "NODE_OPTIONS=--max-http-header-size={YOUR HEADER SIZE} ts-node src/index.ts",
"watch": "nodemon"
},
(It was non-deterministic due to the fact that the token size could be slightly less than 8 KB sometimes, maybe)
If the request is working fine with curl then I think the request header is being modified by some extensions in your browser.
Try opening your client web application in incognito mode ctrl+shift+p in mozilla firefox and ctrl+shift+n in Chrome browser and Test again.
You will get the same response as given by cur if the problem is due to any extension in your browser.

Node/ Angular CORS issue [duplicate]

This question already has answers here:
Why doesn't adding CORS headers to an OPTIONS route allow browsers to access my API?
(36 answers)
Closed 3 years ago.
so I am having this weird issue. I have an application with Node/Angular hosted on the server, working on the same port. But only on one page, there is a CORS error.
So far, I have added allowed CORS before the routes in the app.js.
CODE:
const apiRoutes = require("./routes/api");
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header(
"Access-Control-Allow-Headers",
"Content-Type, Authorization, Content-Length, X-Requested-With, cache-control"
);
res.setHeader(
"Access-Control-Allow-Methods",
"GET,POST,PATCH,DELETE,OPTIONS,PUT"
);
next();
})
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use('/uploads', express.static(path.join(__dirname, './uploads')));
app.use('/api', apiRoutes);
I have also used the cors npm package and allowed it with that as well, but still no luck.
The request parameters of getting the same image from the same directory are attached.
Response param when the image is accessed on page 1
Response param when the same image is blocked CORS
Image for error
EDIT:
const cors = require('cors');
app.use(cors());
app.options('*', cors());
I have also used this, but it doesn't work either.
Request from same origin is getting blocked,
Access to image at 'https://www.pay2mate.com/uploads/1579836295281-Affinity_Logo.png' from origin 'https://pay2mate.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Based on your error;
Access to image at
'https://www.pay2mate.com/uploads/1579836295281-Affinity_Logo.png'
from origin 'https://pay2mate.com' has been blocked by CORS policy: No
'Access-Control-Allow-Origin' header is present on the requested
resource.
You may have confused the difference between your NodeJS API and the web server itself.
As your code shows the image you are requesting is being served by Apache (the web server) and not by your NodeJS API;
URL: https://www.pay2mate.com/uploads/1579836295281-Affinity_Logo.png
server: Apache
accept-ranges: bytes
content-length: 5774
content-type: image/png
date: Mon, 17 Feb 2020 01:41:59 GMT
etag: "69c3450-168e-59cda4d2ef8f3"
last-modified: Fri, 24 Jan 2020 03:24:55 GMT
status: 200
You will either need to direct all requests to your API in your .htaccess file regardless of whether the physical file exists and then stream the file through your API.
Or, you could update your .htaccess file to add this header for you which will then appear on file requests (if you want this wide open like your example);
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>
You can read more about this here; https://enable-cors.org/server_apache.html
If this does not work. Please post more information about your hosting server configuration & the contents of your current .htaccess file

CORS issue with Vue.js and Nodejs

I used vuejs with nodejs, with the vue client address http://localhost:8000, the nodejs server addresses http://localhost:3000.
When calling api, I get cors error CORS preflight channel did not succeed request headers
request
Access-Control-Request-Headers: content-type
Access-Control-Request-Method: POST
Host:localhost: 3000
Origin:http://localhost: 8000
response
Access-Control-Allow-Headers: Origin, X-Requested-With, Accept,content-type
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT,PATH
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 86400
Content-Type:application/json; charset=utf-8
error in response is NS_ERROR_DOM_BAD_URI
If you use expressjs you can simply use nodejs cors lib to enable CORS in your node server.
I strongly advise you to activate it only for dev purposes :
var cors = require('cors')
if (NODE_ENV !== 'production') {
app.use(cors())
}

Nodejs request behaves differently than Postman and Curl

I've been messing with that for a while now and can't seem to figure it out... I'm trying to send a POST request to a device (what device doesn't matter I guess) in order to change it's IP address. Usually, the setup is done through the browser, so I'm trying to emulate that request. It seems to be working fine when I make the request with Postman or Curl but not with the request module from Node.js.
All requests return a 200 OK status code but the latter seems to be not accepted. This is the request I perform using Postman:
POST /configuration_tab/ajax_comb_table_save/network_config/network_config_schema HTTP/1.1
Host: 192.168.1.250
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Cookie: PHPSESSID=mg37okvhkr1eqv1okq99i98i62
Cache-Control: no-cache
Postman-Token: 234ece69-c3f8-2d29-34a5-c40f8e64f708
form=Hostname%3D%26IPv4mode%3Dstatic%26IPv4address%3D192.168.1.250%26
IPv4netmask%3D255.255.255.0%26IPv4gateway%3D0.0.0.0%26DNSmode%3Dmanual%26
IPv4DNS1%3D%26IPv4DNS2%3D%26IpAddrCnflctDetectEnbl%3Denable%26NtpServer%3D%26
SyslogServer%3D%26SyslogPort%3D514%26SshServerEnable%3Denable
This is what I sent through curl:
curl -X POST "http://192.168.1.250/configuration_tab/ajax_comb_table_save/network_config/network_config_schema"
-H "Content-Type:application/x-www-form-urlencoded; charset=UTF-8"
-H "Cookie:PHPSESSID=mg37okvhkr1eqv1okq99i98i62"
-d "form=Hostname%3D%26IPv4mode%3Dstatic%26IPv4address%3D192.168.1.250%26IPv4netmask%3D255.255.255.0%26IPv4gateway%3D0.0.0.0%26DNSmode%3Dmanual%26IPv4DNS1%3D%26IPv4DNS2%3D%26IpAddrCnflctDetectEnbl%3Denable%26NtpServer%3D%26SyslogServer%3D%26SyslogPort%3D514%26SshServerEnable%3Denable"
Again, both of them work fine. Now, this is the code I was using to try the same thing via Node:
let body = "form=Hostname%3D%26IPv4mode%3Dstatic%26IPv4address%3D192.168.1.250%26IPv4netmask%3D255.255.255.0%26IPv4gateway%3D0.0.0.0%26DNSmode%3Dmanual%26IPv4DNS1%3D%26IPv4DNS2%3D%26IpAddrCnflctDetectEnbl%3Denable%26NtpServer%3D%26SyslogServer%3D%26SyslogPort%3D514%26SshServerEnable%3Denable"
request({
url: "http://192.168.1.250/configuration_tab/ajax_comb_table_save/network_config/network_config_schema",
method: "POST",
headers: {
"Cookie": "PHPSESSID=mg37okvhkr1eqv1okq99i98i62",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
},
body: body
}, (err, resp) => {
// Do whatever...
});
Does anyone have an idea what might be different or anything I'm missing? Any help would be appreciated.

how to correct issue with nodejs with react app not loading content properly related to Content Security Policy

I'm currently having issues with my code not deploying on heroku with a "Cannot GET /" message, when I seem to have no issues when running the server on my laptop. I'm not sure if it's a path issue as my console issued the following error: Content Security Policy: The page’s settings blocked the loading of a resource at self (“default-src https://mvpauto.herokuapp.com”). Source: ;(function installGlobalHook(window) {
I have not set up my code to tinker with my response object headers to set the CSP, nor do I have any middleware running outside of body-parser, which I also tried to disable in my debugging to no avail. My headers are as follows:
Server Cowboy
Connection keep-alive
X-Powered-By Express
Content-Security-Policy default-src 'self'
X-Content-Type-Options nosniff
Content-Type text/html; charset=utf-8
Content-Length 139
Date Sun, 01 Oct 2017 04:12:05 GMT
Via 1.1 vegur
Request headers (364 B)
Host
mvpauto.herokuapp.com
User-Agent Mozilla/5.0 (Windows NT 10.0; …) Gecko/20100101 Firefox/55.0
Accept text/html,application/xhtml+xm…plication/xml;q=0.9,*/*;q=0.8
Accept-Language en-US,en;q=0.5
Accept-Encoding gzip, deflate, br
DNT 1
Connection keep-alive
Upgrade-Insecure-Requests 1
Cache-Control max-age=0
These are the headers when running locally successfully using "heroku local"
X-Powered-By Express
Accept-Ranges bytes
Cache-Control public, max-age=0
Last-Modified Sun, 01 Oct 2017 03:26:11 GMT
ETag W/"17f-15ed5f847af"
Date Sun, 01 Oct 2017 04:29:45 GMT
Connection keep-alive
Request headers (439 B)
Host localhost:5000
User-Agent Mozilla/5.0 (Windows NT 10.0; …) Gecko/20100101 Firefox/55.0
Accept text/html,application/xhtml+xm…plication/xml;q=0.9,*/*;q=0.8
Accept-Language en-US,en;q=0.5
Accept-Encoding gzip, deflate
DNT 1
Connection keep-alive
Upgrade-Insecure-Requests 1
If-Modified-Since Sun, 01 Oct 2017 03:26:11 GMT
If-None-Match W/"17f-15ed5f847af"
Cache-Control max-age=0
And then my index.js:
const express = require('express');
const app = express();
const db = require(__dirname + '/../database');
const bodyParser = require('body-parser');
const port = process.env.PORT || 3000;
const path = require('path');
app.use(express.static(path.resolve(__dirname + '/../client/dist')));
const router = require('./routes');
app.use('/', router);
app.get('/', (req, res) => {
res.sendFile(__dirname + '/../client/dist/index.html');
});
app.listen(port, () => console.log('Listening on port ' + port));
I don't have any get request handlers for my root('/') endpoint, since on the client side, a get request is submitted to the '/todos' endpoint on load. I tried adding a '/' handler and having get requests to root result in a res.sendFile('index.html'), which in turn results in a "Forbidden" message. Any help would be much appreciated.
I just found the issue, which was that I had my server.js file in a separate server folder in the root of the app repo. This becomes especially problematic when trying to access my client files which sit in a folder that is a sibling of the server dir, as the only way to traverse to the client directory is through passing through the shared parent, which I don't have access to. This is all gathered from observation and having run 'heroku run ls ~', as I can't find any of this in their documentation nor discussed online elsewhere.

Resources