I have a cross-domain request problem about React - reactjs

I have a problem. When I click the button, an error is reported on the page.
"Access to XMLHttpRequest at 'http://localhost:8000/hello' from origin
'http://localhost:3000' has been blocked by CORS policy: No
'Access-Control-Allow-Origin' header is present on the requested
resource."
Here is client code
function SendRequest() {
axios({
url: "http://localhost:8000/hello",
method: "GET",
}).then((res)=>
{
console.log(res);
});
}
Here is server code
app.use((ctx, next) => {
console.log("ASDFSFDSF");
createProxyMiddleware({
target: "http://localhost:8000",
changeOrigin: true
})
});
The server use koa framework

If you're using express as a backend framework you can install a CORS-Middleware (npm i cors in your backend directory) and use it as an active middleware (globally, so for every incoming request) by calling app.use(cors()) after importing it using const cors = require("cors").
See here for more information about express and CORS Middleware.

That's not a React problem. That's the back-end blocking the request to your app. Read more about CORS.

Related

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 to handle CORS Policy when use fetch function on ReactJs

need help for ReactJs. I still learning reactJs to fetch data from PHP backend. I'm using Xampp as my local server. but when i integrate fetch function on ReactJs, i got CORS policy error.
here is my code from on my App.jsx
useEffect(() => {
fetch("http://localhost:81/opencart/index.php?route=api/create", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ items: [{ id: "xl-tshirt" }] }),
})
.then((res) => res.json())
.then((data) => setClientSecret(data.clientSecret));
}, []);
On my reactJs package.json file i added this
"proxy": "http://localhost:81/"
but still display error on browser console
Access to fetch at 'http://localhost:81/opencart/index.php?route=api/create' 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.
How do I resolve this?
CORS issue is definitely coming from Server. So the ideal way is to set your server to accept your request from cross origin.
Seems you are working with server built with PHP, then check your backend server to add CORS configuration.
For Express.js and others are having several way to add it such as adding 'cors` middleware.

Deno Oak Disable Cors

I am trying to 'connect' my small React JS app with my Deno API backend on my local environment with fetch().
const apiUrl = `http://localhost:8000`;
try{
fetch(apiUrl)
.then((res) => res.json())
.then((repos) => {
console.log(repos);
setAppState({ loading: false, repos: repos });
});
}catch(err){
console.log(err);
}
My app is serving on localhost:3000 and my deno api on localost:8000.
However, I am having problem with CORS:
Access to fetch at 'http://localhost:8000/' 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.
I tried some suggestions like:
add line '"proxy": "http://localhost:8000" to reactjs project packages.json'.
Or to add:
var options = {
method: 'get',
headers: {
"Access-Control-Request-Headers": "*",
"Access-Control-Request-Method": "*"
},
}
fetch(apiUrl, options)
Or to add:
fetch(apiUrl, {mode: 'no-cors'})
However, nothing works in my case. All the time getting the same error and some additional based on suggestions.
So,I need to disable CORS in my reactjs and deno api app to allow local dev communication between frontend and backend.
Solution in my case was pretty easy.
I had to import oakCors into my Deno API app.ts
import { oakCors } from "https://deno.land/x/cors/mod.ts";
after that, just add the excluded origin after app instantiation:
app.use(
oakCors({
origin: "http://localhost:3000"
}),
);
NOTE: I tried to set origin to origin: false and that did not work in my case.
For more options on Deno CORS here is a link: https://deno.land/x/cors
This works just fine:
app.use(oakCors({ origin: "*" }));
For me, I had to first pass oakCors configuration to the app and then the routes.
app.use(oakCors({
origin: 'http://localhost:4200',
optionsSuccessStatus: 200,
}));
app.use(router.routes());
placeapp.use(oakCors()) before your routes like this:
app.use(oakCors())
app.use(route.routes())
this is allow all CORS before to manage the routes

fetching express back-end with react return 405 error (from origin 'null' has been blocked by CORS policy: Response to preflight etc...)

I have a small express/react app. I'm running server side on port 5000 and client side on port 3000. I have the following component on the front-end:
componentDidMount() {
fetch('http://localhost:5000/auth/google',
{
method: 'GET',
headers: {'Content-Type': 'application/json'},
credentials: 'same-origin',
'Access-Control-Allow-Origin': '*'
})
.then(res => {
if (!res.ok) {
throw res;
}
return res.json()
}).then(data => {
this.setState({loading: false, data});
}).catch(err => {
console.error(err);
this.setState({loading: false, error: true});
});
}
on the back-end I have this:
router.get(
"/auth/google",
passport.authenticate("google", { scope: ['Profile','https://www.googleapis.com/auth/analytics.readonly'] })
);
router.get(
"/auth/google/callback",
passport.authenticate("google", { failureRedirect: "/error", session: false }),
function(req, res) {
var token = req.user.token;
request('https://www.googleapis.com/analytics/v3/management/accounts?access_token=' + token,
function (error, response, body) {
console.log(JSON.parse(body).items);
res.send(JSON.parse(body).items)
});
}
);
and here are the error I have:
Failed to load resource: the server responded with a status of 405 ()
and
Access to fetch at 'https://accounts.google.com/o/oauth2/v2/auth?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2Fauth%2Fgoogle%2Fcallback&scope=Profile%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fanalytics.readonly&client_id=blablabla.apps.googleusercontent.com' (redirected from 'http://localhost:5000/auth/google') from origin 'null' 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.
CORS security violation is triggered by your browser which:
has got React code (presumably script bundles) from one server,
is seeing attempts by this code to fetch from another server that is not telling the browser to calm down and tolerate this security violation.
Failed to load resource: the server responded with a status of 405
This means the browser attempted to contact 'another server' prior to fetch and ask if it should tolerate the security violation but 'another server' refused to talk. Technically speaking, the browser has sent HTTP request using HTTP verb OPTIONS and the server responded by indicating it doesn't support this verb.
Access to fetch at 'https://accounts.google.com/o/oauth2/
That's the actual CORS violation detected by the browser which effectively refused to execute fetch.
There are lots of recipes how to calm down the browser so that it would tolerate CORS violations. But the best apprroach is to ensure the violations won't happen so that there is no need to relax the security.
The output of a React application build are .html files and script bundles, possibly source maps. Called build artifacts. If you structure your project so that in both development and production the browser gets everything (build artifacts, API responses) from one single source e.g. Express then there will be no room for CORS issues.

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

Resources