My react app and express server are on different ports - reactjs

Problem/error:
I am running my react app on port 3000 and express on 3001.
error: Access to fetch at 'http://localhost:3001/api' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: 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.
//react code
//this function gets called when a button get pressed
...
post = () => {
const client_data = {info: this.state.input};
const options = {
method: "POST",
headers: {
"Content-Type": "application/json
},
body: JSON.stringify(client_data)
}
fetch("http://localhost:3001/api", options);
}
...
Server is pretty simple
var express = require('express');
var app = express();
app.post('api', (request, response)=>{console.log(request})
(when I add "app.listen(3000)" react stops working)

You have to proxy your requests from react to express. The best way is to let it do your WebPack devServer, having this configuration:
(I assume, your express server is on 3000 and your React app on 3001)
devServer: {
...
...
proxy: {
'/api': {
target: 'http://127.0.0.1:3000/',
},
},
This says, that whichever request to path /api will be redirected to port 3001. Then you fetch to
fetch("/api", options);
Client automatically requests localhost:3001 (port on which the application is running), but the proxy redirects to 3000.

Brief explanation:
When developing react app, react creates a live developing enviroment that runs on -p 3000. However, if I spin up a node backend on -p 3000, the ports collide and the live enviroment crashes.
Solution:
Spin the node backend on a different port (4000)
and make a proxy in the live app
SERVER:
app.listen(4000, () => console.log("server is up on -p 4000")
CLIENT:
In the react app package.json file insert this key/value:
{
...
"proxy": "http://localhost:4000",
...
}

Related

Gettting CORS error on react app vercel deployment backend with render

I have hosted my client side (REACT) with vercel and server side (expressjs & mongoose) with Render.
When I run my client side locally everything works fine however it's not working with vercel deployment. Showing CORS Error.
I have enabled cors for all origins. still it is getting the error on vercel deployment.
here's my axios config for frontend
const axiosPublic = axios.create({
baseURL: BASE_URL,
headers: {
"Content-Type": "application/json",
},
});
here's backend code:
app.use(cors());
Initially I used cors config, which looked like this:
config file
const allowedOrigins = [
"https://rey-server.onrender.com",
"https://reyfurnisher.vercel.app",
"http://localhost:4000",
"http://localhost:3000",
"http://localhost:5000",
];
module.exports = allowedOrigins;
cors options file:
const allowedOrigins = require("./allowedOrigins");
const corsOptions = {
origin: (origin, callback) => {
if (allowedOrigins.indexOf(origin) !== -1 || !origin) {
callback(null, true);
} else {
callback(new Error("Not Allowed by CORS"));
}
},
credentials: true,
optionsSuccessStatus: 200,
};
module.exports = corsOptions;
server.js file:
app.use(cors(corsOptions));
Screenshot of my network tab.
https://prnt.sc/K760DmXAdmYa
It's strange that, when I try to load the page in google chrome the page is empty and nothing loading in the network tab as well. However, in arc, safari and firefox it's showing error in network tabs.
response header
request header
``

React Client Cors issue

I am learning react, I currently have a .net core API running in visual studio on localhost:7071.
The Local API is not running cors as there is no requirement for it to use Cors.
Creating a simple react client using the following will not return data due to a cors error?
I have tried a number of solutions online and none of them work, so how can I make this "simple" react client work without generating the following error
Access to XMLHttpRequest at 'http://localhost:7071/api/Users' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
function GetApiResults(){
const axios = require('axios').default;
axios.defaults.headers.common["Access-Control-Allow-Origin"] = "*";
axios({
method: 'get',
headers: { 'Content-Type': 'application/json' },
url: 'http://localhost:7071/api/Users',
}).then(function (response) {
console.log(response.data);
})
.catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
// always executed
});
}
export default GetResults;
You have a pretty straighforward description of the issue, browser expects the external resouces you are using (API in your case, external in terms it is not on same port) to provide CORS headers. If they are not set - browser will not execute the request. It will execute the request if you open the resource URL in browser tab, but if you are on localhost:3000 - any requests initiated by this page to anything that is not on localhost:3000 will require CORS to be set.
https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-6.0
Browser security prevents a web page from making requests to a different domain than the one that served the web page. This restriction is called the same-origin policy. The same-origin policy prevents a malicious site from reading sensitive data from another site.
So either enable CORS support in your backend, either use CRA feature called Proxy: https://create-react-app.dev/docs/proxying-api-requests-in-development/
I prefer the manual proxy configuration, at the very end of the article.
Important: this proxy is for DEVELOPMENT only!
Here is a step-by-step instruction, just tested:
Install npm install http-proxy-middleware --save
Add src/setupProxy.js with content:
const { createProxyMiddleware } = require("http-proxy-middleware");
module.exports = function (app) {
app.use(
"/api",
createProxyMiddleware({
// I have a different port and Visual Studio might randomly change it
// Fix: edit running configuration
// https://stackoverflow.com/questions/70332897/how-to-change-default-port-no-of-my-net-core-6-api
// Notice: no /api at the end of URL, it will be added.
// more details at: https://www.npmjs.com/package/http-proxy-middleware
target: "https://localhost:7002",
changeOrigin: true,
// Im using .net core 6 starting api template
// which is running with a self-signed ssl cert with https enabled
secure: false
})
);
};
Modify your AXIOS configuration object to use new URL:
function GetApiResults() {
const axios = require("axios").default;
axios({
method: "get",
headers: { "Content-Type": "application/json" },
url: "/api/WeatherForecast"
})
/* ... */
}
Note: Im using default web api project, only changed [Route("api/[controller]")] (added api/) for Controller.
Restart the app and watch for logs from npm start output, proxy can log some errors there.
CORS is a browser feature. So, the browser you are using to access the React app must require you to use CORS. You need to setup CORS on your backend and allow connections from remote origin.
It will be good if you add CORS enabling code on Server Side. if your server-side app is in Express JS then add below middleware-
var app = express();
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
// res.header("Access-Control-Allow-Origin", "http://localhost:3000"); or add your react app url.
next();
});

How Do I Proxy Requests for Rsocket on React app

I need to proxy both rsocket and http in react app. I was successful adding proxy to http request by adding to package json
"proxy": "http://192.184.24.12:82"
How do I do it to rsocket that sits on top of websocket.
Need to work http and rsocket simultaneously
let client = new RSocketClient({
transport: new RSocketWebSocketClient(
{
url: "ws://localhost:7000/ws",
wsCreator: (url) => new WebSocket(url),
debug: true,
},
BufferEncoders
),
setup: {
dataMimeType: "application/json",
metadataMimeType: MESSAGE_RSOCKET_COMPOSITE_METADATA.string,
keepAlive: 5000,
lifetime: 60000,
},
});
If you use rsocket in browser - then you use a websocket transport underneath. That said, if your proxy can proxy websocket (and I bet it can) you can proxy rsocket

Express CORs policy preventing Apollo client from fetching from server

I'm running a react dev server on http://localhost:3000 and an express server on http://localhost:8080 and am using an Apollo Client to query the server. To enable session data to be passed from client to server I have added the credentials: "include" parameter when initializing the Apollo Client.
I've added the following line in my express server (before the routes are defined) to configure cors:
app.use(cors({ credentials: true, origin: "http://localhost:3000" }));
However, when executing queries, the following error is thrown:
Access to fetch at 'http://localhost:8080/graphql' from origin 'http://localhost:3000' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.
Why is the header response showing up as *? Am I configuring CORs incorrectly or am I missing something else?
The problem I was running into here was that despite enabling CORS for express:
app.use(cors({ credentials: true, origin: "http://localhost:3000" }));
The GraphQL middleware was over-riding the setting. Make sure to pass the cors: false param as shown below if using an Apollo Server and associated middleware.
gqlServer.applyMiddleware({ app, path: "/graphql", cors: false });
This error is a CORS error generated by the browser. use npm install --save http-proxy-middleware in your front end and add setupProxy.js file in frontend/src/setupProxy.js
setupProxy.js
//run defferent ports for website and api server
const proxy = require('http-proxy-middleware');
module.exports = function(app) {
app.use(proxy('/api/', { target: 'http://localhost:8080/' })); //make change as per your application (So you can access your data on http://localhost:8080/api/ )
};
Alternate solution
If you are using webpack dev server, here's another way to proxy requests without making changes on NodeJS. Adding this to package.json:
"proxy": "http://localhost:8080"
Should allow webpack to proxy requests made to http://localhost:3000 to http://localhost:8080.
But this would mean request will need to be made to http://localhost:3000 instead of http://localhost:8080.
Since you have credentials: true, you should include the credentials in your fetch call:
fetch(url, {
credentials: 'include'
})
or
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://example.com/', true);
xhr.withCredentials = true;
xhr.send(null);
This will send the request with the headers set to Access-Control-Allow-Credentials: true
without this, it will be rejected.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials

Apollo client query error: "Network error: Failed to fetch" How to troubleshoot?

An Apollo server is setup, and it responds correctly to the query when using graphiql.
An existing react-redux app with server side rendering needs to start using graphql and make this query.
A component of this app has been setup to do the same query, it seems to be doing the network request, but it fails with
Error: {"graphQLErrors":[],"networkError":{},"message":"Network error: Failed to fetch"}
Any troubleshooting advice?
It really is cors issue. I tried to fix it by using express. But it didn't work with Apollo GraphQL.
const corsOptions = {
origin: "http://localhost:3000",
credentials: true
};
app.use(cors(corsOptions));
So, I tried configuring cors inside GraphQL server and It Worked.
For Apollo Server
const corsOptions = {
origin: "http://localhost:3000",
credentials: true
};
const server = new ApolloServer({
typeDefs,
resolvers,
cors: corsOptions
});
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
For GraphQL Yoga
const options = {
cors: corsOptions
};
server.start(options, () =>
console.log("Server is running on http://localhost:4000")
);
I was running apollo client on localhost, and apollo server on someDomain.com, so it was a CORS issue. After loading the page that does the query in chrome incognito mode and refreshing, this error was found in the chrome dev tools console:
httpLink.js:71 OPTIONS https://someDomain.com/graphql 405 (Method Not Allowed)
(anonymous) # httpLink.js:71
...
(index):1 Failed to load https://someDomain.com/graphql: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://localhost:8443' is therefore not allowed access. The response had HTTP status code 405. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
A quick fix for this (test only) setup was to setup cors on the express apollo server like this post suggests.
https://blog.graph.cool/enabling-cors-for-express-graphql-apollo-server-1ef999bfb38d
All you need to do to make the following work is to enable cors library for your Apollo-Graphql server
yarn add cors / npm install cors
Now got to you app.js or server.js ( Basically the entry file of your server )
add the following lines to it
const cors = require('cors');
app.use(cors()); // Make sure you have express initialised before this.
Try using the cors middleware at the top of your code. This initializes the cross-origin resource sharing first before the graphql endpoint is created.
enter const { urlencoded } = require("express");
const express = require("express");
const app = express(); //create an express application
const helmet = require("helmet"); //require helment from node modules
const cors = require("cors"); //cross-origin-resource sharing
const mR = require("./routes/main");
const schema = require("./graph-schema/schema");
const mongoose = require("mongoose");
//cross-origin-resources-sharing defined at the top before your graphql endpoint
app.use(
cors({
optionsSuccessStatus: 200, //option sucess status
origin: "http://localhost:3000", //origin allowed to access the server
})
);
//connect to database
mongoose.connect("mongodb://localhost:27017/Graphql_tutorial", {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
});
//graphql area
const { graphqlHTTP } = require("express-graphql"); //This allows express to understand graphql and lunch its api.
app.use(
"/graphql",
graphqlHTTP({
schema,
graphiql: true,
})
);//code here
You can have this error as well if you pass a null HEADER in your request through Apollo, so something like:
const middlewareLink = setContext(() => ({
headers: {
'authorization': `Bearer ${FeedierExchanger.token}` || null
}
}));
Change it to:
const middlewareLink = setContext(() => ({
headers: {
'authorization': `Bearer ${FeedierExchanger.token}` || ''
}
}));
Or remove this part:
|| ''
If you've the correct backend validation.

Resources